获取特定属性中的不同值

时间:2012-05-10 11:03:04

标签: xml xpath distinct

我有以下XML代码:

<!-- language: xml -->
<Stats>
  <Stat>
    <Data Name="Value">63.76</Data>
    <Data Name="Entity">first</Data>
  </Stat>
  <Stat>
    <Data Name="Value">51.23</Data>
    <Data Name="Entity">second</Data>
  </Stat>
  <Stat>
    <Data Name="Value">46.1</Data>
    <Data Name="Entity">third</Data>
  </Stat>
  <Stat>
    <Data Name="Value">61.21</Data>
    <Data Name="Entity">first</Data>
  </Stat>
</Stats>

我想过滤'Data [@ Name ='Entity']的位置。使用xpath:/Stats/Stat/Data[@Name="Entity"]返回: 第一 第二 第三 第一

但我希望结果是独一无二的。所以我只得到: 第一 第二 第三

编辑:我需要这个适用于xpath版本1.0。

2 个答案:

答案 0 :(得分:3)

您需要说出哪个版本的XPath。在XPath 2.0中,它是微不足道的:

distinct-values(/Stats/Stat/Data/@Name)

答案 1 :(得分:3)

使用此XPath 1.0表达式

/Stats/Stat
   [Data/@Name='Entity'
  and
   not(Data[@Name='Entity']  = following-sibling::Stat/Data[@Name = 'Entity'])
   ]
    /Data[@Name='Entity']

基于XSLT的验证

<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:template match="/">
     <xsl:copy-of select=
      "/Stats/Stat
           [Data/@Name='Entity'
          and
           not(Data[@Name='Entity']  = following-sibling::Stat/Data[@Name = 'Entity'])
           ]
            /Data[@Name='Entity']
      "/>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档(通过更正格式不正确的文本生成):

<Stats>
  <Stat>
    <Data Name="Value">63.76</Data>
    <Data Name="Entity">first</Data>
  </Stat>
  <Stat>
    <Data Name="Value">51.23</Data>
    <Data Name="Entity">second</Data>
  </Stat>
  <Stat>
    <Data Name="Value">46.1</Data>
    <Data Name="Entity">third</Data>
  </Stat>
  <Stat>
    <Data Name="Value">61.21</Data>
    <Data Name="Entity">first</Data>
  </Stat>
</Stats>

评估上述XPath表达式,并将选定的节点复制到输出中:

<Data Name="Entity">second</Data>
<Data Name="Entity">third</Data>
<Data Name="Entity">first</Data>

注意:如果您只需要文本节点(“first”,“second”和“third”),只需使用此单个XPath表达式:

/Stats/Stat
   [Data/@Name='Entity'
  and
   not(Data[@Name='Entity']  = following-sibling::Stat/Data[@Name = 'Entity'])
   ]
    /Data[@Name='Entity']
      /text()