Не уверен, что это самый эффективный способ сделать это, но, надеюсь, это даст вам несколько советов, если на самом деле он не выполняет свою работу полностью:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="*[count(*)!=0]">
<xsl:param name="prefix" />
<xsl:value-of select="substring(concat($prefix,'.',name()),2)" />
<xsl:text> = new jsonObject(); </xsl:text>
<xsl:apply-templates select="*">
<xsl:with-param name="prefix" select="concat($prefix,'.',name())" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*[count(*)=0]">
<xsl:param name="prefix" />
<xsl:choose>
<xsl:when test="count(../*[name()=name(current())]) != 1">
<xsl:if test="position()=1">
<xsl:value-of select="substring(concat($prefix,'.',name()),2)" />
<xsl:text> = new array(); </xsl:text>
<xsl:text>"arraystart" </xsl:text>
<xsl:value-of select="substring(concat($prefix,'.',name()),2)" />
<xsl:text>[aindex] = new jsonObject(); </xsl:text>
<xsl:value-of select="substring(concat($prefix,'.',name()),2)" />
<xsl:text>[aindex] = "holder"; </xsl:text>
<xsl:text>"endarray" </xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(concat($prefix,'.',name()),2)" />
<xsl:text> = "holder"; </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
У меня изначально был второй шаблонсоответствует *[text()]
, но, к сожалению, ваш <subnode></subnode>
эквивалентен <subnode />
, у которого вообще нет текста, а есть текст с длиной 0.Это означает, что предполагается, что любой узел, у которого нет дочерних элементов, должен обрабатываться так, как если бы он был текстовым.
Тест «когда» во втором шаблоне немного запутан, но в основном он проверяет, является ли текущий узелодин из нескольких с таким именем, и если это первый такой узел, он выводит массив данных, в противном случае ничего не делает.Большой недостаток в том, что такие массивы могут быть только текстовыми узлами;например, если в вашем образце xml вместо node2
было node1
, так что у вас было два элемента node1
в myroot
, вы не увидели бы ничего из "arraystart".Если это может произойти, понадобится немного изменить дизайн, но, надеюсь, здесь достаточно полезных примеров, чтобы помочь.
Редактировать: Забыл два небольших пункта:
Я использую
для символа новой строки;замените его на
, если требуется.
Кроме того, биты substring(something,2)
связаны с тем, что он добавляет точку, за которой следует имя узла, каждый раз, когда он понижается до уровня, что означает, что он имеет правоначало каждый раз.substring(something,2)
просто берет все, начиная со 2-го символа, другими словами, обрезая этот период.