我想使用XSLT
输出类似于以下内容的内容XML:
<myroot>
<node1>
<subnode1>somestuff</subnode1>
<subnode2>otherstuff</subnode2>
</node1>
<node2>
<subnode2></subnode2>
<subnode3>stuff here</subnode3>
</node2>
<node3>
<subnode>stuff</subnode>
<subnode>stuff</subnode>
<subnode>other</subnode>
</node3>
</myroot>
我不知道给定实例的节点名称。
我希望我的输出看起来像这样:
myroot = new jsonObject();
myroot.node1 = new jsonObject();
myroot.node1.subnode1 = "holder";
myroot.node1.subnode2 = "holder";
myroot.node2 = new jsonObject();
myroot.node2.subnode2 = "holder";
myroot.node2.subnode3 = "holder";
myroot.node3 = new jsonObject();
myroot.node3.subnode = new array();
"arraystart"
myroot.node3.subnode[aindex] = new jsonObject();
myroot.node3.subnode[aindex] = "holder";
"endarray"
重点:
答案 0 :(得分:1)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="name" match="*" use="name()"/>
<xsl:template match="text()"/>
<xsl:template match="*[*]">
<xsl:param name="name"/>
<xsl:value-of select="concat($name,
name(),
' = new jsonObject();
')"/>
<xsl:apply-templates>
<xsl:with-param name="name" select="concat($name,name(),'.')"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*[not(*)][count(../*|key('name',name()))!=count(key('name',name()))]">
<xsl:param name="name"/>
<xsl:value-of select="concat($name,
name(),
' = "holder";
')"/>
</xsl:template>
<xsl:template match="*[not(*)][1][count(../*|key('name',name()))=count(key('name',name()))]" priority="1">
<xsl:param name="name"/>
<xsl:value-of select="concat($name,
name(),
' = new array();
',
'"arraystart"
')"/>
<xsl:apply-templates select="following-sibling::*" mode="array">
<xsl:with-param name="name" select="concat($name,name(),'.')"/>
</xsl:apply-templates>
<xsl:text>"endarray"</xsl:text>
</xsl:template>
<xsl:template match="*" mode="array">
<xsl:param name="name"/>
<xsl:value-of select="concat($name,
'[aindex] = ')"/>
<xsl:choose>
<xsl:when test="contains(.,'stuff')">new jsonObject();
</xsl:when>
<xsl:otherwise>"holder";
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
输出:
myroot = new jsonObject();
myroot.node1 = new jsonObject();
myroot.node1.subnode1 = "holder";
myroot.node1.subnode2 = "holder";
myroot.node2 = new jsonObject();
myroot.node2.subnode2 = "holder";
myroot.node2.subnode3 = "holder";
myroot.node3 = new jsonObject();
myroot.node3.subnode = new array();
"arraystart"
myroot.node3.subnode.[aindex] = new jsonObject();
myroot.node3.subnode.[aindex] = "holder";
"endarray"
但我认为你应该改进你的目标。
答案 1 :(得分:0)
不确定这是否是最有效的方法,但希望这应该给你一些指示,如果它确实没有完全完成这项工作:
<?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长度的文字。这意味着它假定任何没有子节点的节点都应该被视为文本。
第二个模板中的'when'测试有点复杂,但它基本上检查当前节点是否是具有该名称的多个节点之一,如果它是第一个这样的节点,则输出数组内容,否则什么也没做。这里最大的缺点是这样的数组只能是文本节点;例如,如果您的示例xml具有node1
代替node2
,以致node1
下有两个myroot
元素,则您将看不到任何“arraystart”东西。如果可能发生这种情况,则需要进行一些重新设计,但希望这里有足够的有用示例来帮助。
编辑:忘了两个小点:
我正在使用
作为换行符;如果需要,请用
代替。
此外,substring(something,2)
位是因为它每次下降一级时附加一个句点后跟节点名称,这意味着它每次都有一个权限。 substring(something,2)
只需要从第二个角色开始,换句话说,切断那段时间。