我在使用XML和XSLT时遇到了问题。我想创建一个如下所示的XML文件:
<Root>
<TopNode>
<ChildNode>
<!-- Some elements -->
<ListOfChilds>
<ChildNode/> <!-- 0 to N ChildNodes within a Childnode which can again have ChildNodes as well and so on -->
</ListOfChilds>
<!-- Some more elements -->
</ChildNode>
<ChildNode>
...
</ChildNode>
</TopNode>
<Root>
正如您所看到的,需要进行某种递归,因为每个ChildNode都可以包含多个可以包含多个ChildNode的ChildNode ......依此类推。我尝试使用<Root>
,<TopNode>
和<ChildNode>
元素的模板来实现此目的。我的XSLT看起来像这样:
<xsl:template match="/">
<Root>
<xsl:apply-templates select="TopNode"/>
</Root>
</xsl:template>
<xsl:template match="TopNode">
<TopNode>
<xsl:apply-templates select="ChildNode"/>
</TopNode>
</xsl:template>
<xsl:template match="ChildNode">
<ChildNode>
<!-- Some elements -->
<ListOfChilds>
<xsl:if test="ChildNode">
<xsl:apply-templates select="ChildNode"/>
</xsl:if>
</ListOfChilds>
<!-- Some more elements -->
</ChildNode>
</xsl:template>
但是,我在XML文件中获得的唯一输出是<Root/>
。你能告诉我在转型中出了什么问题吗?理论上我是否想要这样做,或者我应该尝试一种完全不同的方法?我现在真的很丢失,任何帮助都会非常感激!谢谢!
答案 0 :(得分:1)
如果您使用xsl:apply-templates
(适用于子项),则XSLT会自动完成递归。如果您有这些子项的匹配模板(并且确实如此)并在其中应用模板,则会有递归。你走在正确的轨道上。
<xsl:if test="ChildNode"> <xsl:apply-templates select="ChildNode"/> </xsl:if>
这不是必需的。如果有ChildNode
个元素,则仅应用模板有效,因此xsl:if
是多余的。
从本质上讲,你使用正确的方法,但你在开始时犯了一个小错误:
<xsl:apply-templates select="TopNode"/>
此处的上下文节点是/
,即根节点。但您的元素不是TopNode
,而是Root
。将其更改为Root/TopNode
,您将看到输出。
答案 1 :(得分:0)
这是一个使用递归模板的简单示例。
此嵌套子合约的合约清单
<contracts>
<contract id="1">
<supplier>koos</supplier>
<price>1000000</price>
<subcontracts>
<contract id="1.1">
<supplier>piet</supplier>
<price>500000</price>
</contract>
<contract id="1.2">
<supplier>jan</supplier>
<price>500000</price>
</contract>
</subcontracts>
</contract>
<contract id="2">
<supplier>gert</supplier>
<price>3000</price>
<subcontracts>
<contract id="2.1">
<supplier>piet</supplier>
<price>1000</price>
</contract>
<contract id="2.2">
<supplier>jan</supplier>
<price>1000</price>
<subcontracts>
<contract id="2.2.1">
<supplier>kleinjan</supplier>
<price>10</price>
</contract>
</subcontracts>
</contract>
<contract id="2.3">
<supplier>awie</supplier>
<price>1000</price>
</contract>
</subcontracts>
</contract>
</contracts>
可以使用此模板进行转换
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/contracts">
<xsl:apply-templates select="contract"/>
</xsl:template>
<xsl:template match="contract">
<xsl:value-of select="supplier"/><xsl:text> </xsl:text><xsl:value-of select="price"/>
<xsl:apply-templates select="subcontracts"/>
</xsl:template>
</xsl:stylesheet>
生成此输出
koos 1000000
piet 500000
jan 500000
gert 3000
piet 1000
jan 1000
kleinjan 10
awie 1000