如何使用XPATH从XML文档中选择不同的值?

时间:2010-05-20 07:18:57

标签: xml xslt xpath

如何使用XPATH仅为XML文档选择不同的元素?我尝试使用'distinct-values'函数,但由于某种原因它不起作用..

XML类似于以下内容:

<catalog>

<product>
<size>12</size>
<price>1000</price>
<rating>1</rating>
</product>

<product>
<size>10</size>
<price>1000</price>
<rating>1</rating>
<year>2010</year>
</product>

</catalog>

所以我想得到的是所有产品元素的不同子元素列表。在给定的例子中,它将是 - 大小,价格,评级,年份 我的xpath类似于:distinct-values(catalog / product / *)

3 个答案:

答案 0 :(得分:17)

在XPath 2.0中

distinct-values(/*/*/*/name(.))

在XPath 1.0中,使用单个XPath表达式无法生成

使用XSLT 1.0

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
   <xsl:for-each select=
   "/*/*/*[not(../following::*/*
                       [not(name() = name(current()))]
               )
           ]">
     <xsl:value-of select="concat(name(), ' ')"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换后,生成所需结果

size price rating year

使用密钥

进行更有效的XSLT 1.0转换
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:key name="kpchildByName"
  match="product/*" use="name()"/>

 <xsl:template match="/">
   <xsl:for-each select=
   "/*/*/*
         [generate-id()
         =
          generate-id(key('kpchildByName', name())[1])
          ]">
     <xsl:value-of select="concat(name(), ' ')"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:3)

distinct-values()在XPath 2.0中可用。你在用它吗?

如果distinct-values()不可用,获取不同值的标准方法是使用not(@result = preceding:: @result)获取唯一的@result。它只会给你第一次出现。

答案 2 :(得分:3)

您需要元素名称的不同值 - 例如:

distinct-values($catalog/product/*/name(.))