XPath获取唯一元素名称

时间:2009-12-31 23:26:30

标签: xslt xpath

我想使用XPath来获取XML文件中出现的所有元素的名称列表。但是,我不希望重复任何名称,因此不应匹配与前一个元素同名的元素。到目前为止,我已经:

*[not(local-name() = local-name(preceding::*))]

执行正常,但它会重复出现。为什么要吐出重复的内容,如何消除它们? (我正在使用Firefox的XPath引擎。)

3 个答案:

答案 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将是不同元素名称的字典。