目前,我正在努力让我的XSLT正常运行。我试图将XML转换为无序列表,其子项位于子无序列表中。问题是如果一个人没有孩子,XSL会创建空的列表元素。
XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Trees.xsl"?>
<Tree>
<Person ID="1" FirstName="test" LastName="" ChildOf="0" />
<Person ID="2" FirstName="test2" LastName="" ChildOf="1" />
<Person ID="3" FirstName="test3" LastName="" ChildOf="1" />
<Person ID="4" FirstName="test4" LastName="" ChildOf="1" />
<Person ID="6" FirstName="test6" LastName="" ChildOf="3" />
<Person ID="5" FirstName="test5" LastName="" ChildOf="0" />
</Tree>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Person">
<ul><li><xsl:value-of select="@FirstName" /></li>
<li><xsl:apply-templates select="../Person[@ChildOf=current()/@ID]" />
</li></ul>
</xsl:template>
</xsl:stylesheet>
我已经尝试使用if检查FirstName是否为空,但它不起作用。错误在哪里。
答案 0 :(得分:3)
我建议你这样试试:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="children" match="Person" use="@ChildOf" />
<xsl:template match="/Tree">
<ul>
<xsl:apply-templates select="Person[@ChildOf=0]"/>
</ul>
</xsl:template>
<xsl:template match="Person">
<li>
<xsl:value-of select="@FirstName" />
</li>
<xsl:variable name="children" select="key('children', @ID)" />
<xsl:if test="$children">
<ul>
<xsl:apply-templates select="$children" />
</ul>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
更简单,更短,更有效的解决方案(无变量,无条件指令):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kPersById" match="Person" use="@ID"/>
<xsl:key name="kChildrenOf" match="Person" use="@ChildOf"/>
<xsl:template match="/*">
<xsl:apply-templates select="Person[not(key('kPersById', @ChildOf))][1]" mode="start"/>
</xsl:template>
<xsl:template match="Person" mode="start">
<ul>
<li><xsl:value-of select="@FirstName" /></li>
<xsl:apply-templates select="key('kChildrenOf', @ID)[1]" mode="start"/>
<xsl:apply-templates select="key('kChildrenOf', @ChildOf)[position() > 1]"/>
</ul>
</xsl:template>
<xsl:template match="Person">
<li><xsl:value-of select="@FirstName" /></li>
<xsl:apply-templates select="key('kChildrenOf', @ID)[1]" mode="start"/>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<Tree>
<Person ID="1" FirstName="test" LastName="" ChildOf="0" />
<Person ID="2" FirstName="test2" LastName="" ChildOf="1" />
<Person ID="3" FirstName="test3" LastName="" ChildOf="1" />
<Person ID="4" FirstName="test4" LastName="" ChildOf="1" />
<Person ID="6" FirstName="test6" LastName="" ChildOf="3" />
<Person ID="5" FirstName="test5" LastName="" ChildOf="0" />
</Tree>
产生了想要的正确结果:
<ul>
<li>test</li>
<ul>
<li>test2</li>
<li>test3</li>
<ul>
<li>test6</li>
</ul>
<li>test4</li>
</ul>
<li>test5</li>
</ul>
请注意:
此解决方案不依赖于具有Person
的顶级ChildOf="0"
元素。实际上,对于顶级元素,可以完全省略此属性,或者不同的顶部元素可以具有具有不同值的ChildOf
属性 - 例如,当这些属性已被&#34; cut&#34;来自另一个更大的等级。