XPath 2.0 解决方案和当前接受的答案都非常低效 (O(N^2))。
此解决方案具有亚线性复杂度:
<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="kElemsByName" match="/*/*"
use="name()"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/*[generate-id()
=
generate-id(key('kElemsByName', name())[last()])
]"/>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<root>
<a>One</a>
<a>Two</a>
<b>Three</b>
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
</root>
产生想要的正确结果:
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
说明:这是Muenchian grouping 的修改变体——所以不是第一个。但每组中的最后一个节点被处理。
II XPath 2.0 单线:
用途:
/*/*[index-of(/*/*/name(), name())[last()]]
使用 XSLT 2.0 作为 XPath 2.0 主机进行验证:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select=
"/*/*[index-of(/*/*/name(), name())[last()]]"/>
</xsl:template>
</xsl:stylesheet>
当对同一个 XML 文档(前面提供)应用此转换时,会产生相同的正确结果:
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>