我喜欢XML
<root>
<a>One</a>
<a>Two</a>
<b>Three</b>
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
</root>
Run Code Online (Sandbox Code Playgroud)
并且需要选择root中任何子节点名称的最后一次出现.在这种情况下,所需的结果列表将是:
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏!
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>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的XML文档时:
<root>
<a>One</a>
<a>Two</a>
<b>Three</b>
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
</root>
Run Code Online (Sandbox Code Playgroud)
产生了想要的正确结果:
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
Run Code Online (Sandbox Code Playgroud)
说明:这是Muenchian分组的修改变体- 所以不是第一个.但是处理了每个组中的最后一个节点.
II XPath 2.0 one-liner:
使用:
/*/*[index-of(/*/*/name(), name())[last()]]
Run Code Online (Sandbox Code Playgroud)
使用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>
Run Code Online (Sandbox Code Playgroud)
当此转换应用于同一XML文档(前面提供)时,会生成相同的正确结果:
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
Run Code Online (Sandbox Code Playgroud)
基于 XSLT 的解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="root/*">
<xsl:variable name="n" select="name()"/>
<xsl:copy-of
select=".[not(following-sibling::node()[name()=$n])]"/>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
产生的输出:
<c>Four</c>
<a>Five</a>
<b>
<a>Six</a>
</b>
Run Code Online (Sandbox Code Playgroud)
第二种解决方案(您可以将其用作单个 XPath 表达式):
<xsl:template match="/root">
<xsl:copy-of select="a[not(./following-sibling::a)]
| b[not(./following-sibling::b)]
| c[not(./following-sibling::c)]"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2567 次 |
最近记录: |