我只想处理每个 id 的最后一个节点。以下是我根据一些阅读尝试过的内容:
<xsl:for-each select="//parent/child">
<xsl:sort select="@id"/>
<xsl:if test="not(@id=following-sibling::*/@id)">
<xsl:element name="child">
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
但这似乎不起作用。我的输出仍然包含所有三个元素。关于我可以做些什么来纠正我的问题的任何想法?
这段代码的问题是,即使节点在排序的节点集中,它们following-sibling
的 s 仍然是文档中的。
为了使这段代码能够工作,首先要创建一个全新的文档,其中的节点以所需的方式排序,然后(在 XSLT 1.0 中,必须使用xxx:node-set()
生成的 RTF 上的扩展来使其成为普通的 XML 文档) 在本文档中,节点根据需要具有其兄弟姐妹。
解决方案:
此转换提供了一种可能的 XSLT 1.0 解决方案,它不需要使用扩展函数:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kchildById" match="child" use="@id"/>
<xsl:template match="/*">
<t>
<xsl:apply-templates select=
"*/child[generate-id()
=
generate-id(key('kchildById',
@id)[last()]
)
]
"/>
</t>
</xsl:template>
<xsl:template match="child">
<child>
<xsl:value-of select="@name"/>
</child>
</xsl:template>
</xsl:stylesheet>
当应用于提供的 XML 片段时(包装在顶部元素中以成为格式良好的 XML 文档并添加第二个版本id="2"
):
<t>
<parent>
<child id="1" name="Child 1 Version 1" />
</parent>
<parent>
<child id="2" name="Child 2 Version 1" />
</parent>
<parent>
<child id="1" name="Child 1 Version 2" />
</parent>
<parent>
<child id="2" name="Child 2 Version 2" />
</parent>
</t>
产生想要的结果:
<t>
<child>Child 1 Version 2</child>
<child>Child 2 Version 2</child>
</t>
请注意:使用 Muenchian 方法进行分组。