我想使用XPath来获取XML文件中出现的所有元素的名称列表。但是,我不希望重复任何名称,因此不应匹配与前一个元素同名的元素。到目前为止,我已经:
*[not(local-name() = local-name(preceding::*))]
执行正常,但它会重复出现。为什么要吐出重复的内容,如何消除它们? (我正在使用Firefox的XPath引擎。)
答案 0 :(得分:6)
在XPath 2.0中有效:
distinct-values(//*/name())
答案 1 :(得分:5)
您正在获得重复项,因为您的过滤器未按您认为的方式进行评估。
local-name()函数返回节点集中 第一个节点 的本地名称。
谓词过滤器唯一有效的时间是元素恰好与前一个元素的名称相同。
我认为你无法通过纯粹的 XPATH 1.0 灵魂来完成你想要的任务。您可以在 XPATH 2.0 中执行此操作,但这不适用于Firefox。
在 XSLT 中,您可以使用 meunchien method 来完成您想要的操作。
以下是一个例子。您没有提供任何示例XML,因此我保持它非常通用(例如// *匹配文档中的所有元素):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="xml"/>
<xsl:key name="names" match="//*" use="local-name(.)"/>
<xsl:template match="/">
<xsl:for-each select="//*[generate-id(.) = generate-id(key('names', local-name(.)))]">
<!--Do something with the unique list of elements-->
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:1)
我建议首先获取所有元素的列表,然后遍历列表并将它们添加到字典中以检测重复项。
例如,在伪代码中:
var allElements = doc.select("//node()");
var distinctElementTypes = new object();
foreach (var elem in allElements) {
distinctElementTypes[elem.name] = elem.name;
}
现在distinctElementTypes将是不同元素名称的字典。