【问题标题】:Get distinct values within specific attributes获取特定属性中的不同值
【发布时间】:2012-05-10 11:03:04
【问题描述】:

我有以下 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 版工作。

【问题讨论】:

  • 我看过这篇文章,但是 - 我不认为这篇文章是重复的。那里的 XML 代码:63.76 first 我的 XML 代码:63.76 first
  • Bouke Groenescheij:我的回答有用还是您还有问题?

标签: xml xpath distinct


【解决方案1】:

使用这个 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()

【讨论】:

  • 太棒了!非常感谢您快速准确的回复。我一直在寻找这个很长时间。尤其是最后一个 Note 做到了 - XSLT 是一个很好的奖励!
  • @BoukeGroenescheij:不客气。是的,XPath 和 XSLT 都是迷人、强大和优雅的语言。
【解决方案2】:

您需要说明 XPath 的版本。在 XPath 2.0 中,这很简单:

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

【讨论】:

  • 谢谢。你是对的 - 抱歉,我需要这个用于 XPath 1.0。
  • 顺便说一下,上面的代码没有给出想要的结果,因为它返回了值和实体。将其更改为: distinct-values(/Stats/Stat/Data[@Name='Entity]) 它可以工作 - 现在我需要将其转换为 XPath 版本 1.0...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
相关资源
最近更新 更多