我有一些像这样的XML:
<?xml version="1.0" encoding="UTF-8"?>
<Results>
<Build>
<Test>
<car value=""/>
<car value="abc"/>
<car value=""/>
<car value="xyz"/>
</Test>
</Build>
<Build>
<Test>
<car value=""/>
<car value="xyz"/>
<car value="xyz"/>
<car value="mno" />
</Test>
</Build>
<Build>
<Test>
<car value=""/>
<car value="xyz"/>
<car value="xyz"/>
<car value="mno" />
</Test>
</Build>
</Results>
我希望第二个Build节点元素出来像这样:
XYZ
MNO
我尝试了很多方法。请参考下面的代码。它适用于Build [1]但是当我试图运行它以获得特殊性Build [2]和Build [3]时,输出不是预期的。
<xsl:template match="Results">
<xsl:apply-templates select="Build[2]" />
</xsl:template>
<xsl:template match="Build">
<html>
<body>
<xsl:for-each select="Test/car[not(@value = (preceding:: car/@value))]">
<xsl:sort select="@value" />
<xsl:if test="@value!=''">
<li>
<xsl:value-of select='@value' />
</li>
</xsl:if>
</xsl:for-each>
</body>
</html>
</xsl:template>
它给了我这个输出:
<html>
<body>
<li>mno</li>
</body>
</html>
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
已经有good answer here at SO。根据您的特殊情况,您至少有以下两种解决方案:
在XSLT-2.0中,您拥有distinct-values
函数,只需使用此for-each
循环即可轻松实现此功能。
<xsl:for-each select="distinct-values(Test/car/@value)">
<xsl:sort select="." />
<xsl:if test=".!=''">
<li>
<xsl:value-of select='.' />
</li>
</xsl:if>
</xsl:for-each>
在XSLT-1.0中,以下解决方案将起作用。它有点复杂,但与你的方法非常相似:
<xsl:template match="Build">
<html>
<body>
<xsl:for-each select="Test/car[@value!='' and not(@value=preceding-sibling::car/@value)]">
<xsl:sort select='@value' />
<li>
<xsl:value-of select='@value' />
</li>
</xsl:for-each>
</body>
</html>
</xsl:template>