问题
I've got the following XML Code:
<!-- 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>
I want to filter only where 'Data[@Name='Entity']. Using xpath: /Stats/Stat/Data[@Name="Entity"]
returns:
first
second
third
first
But I want the results to be unique. So I only get: first second third
EDIT: I need this to work for xpath version 1.0.
回答1:
Use this XPath 1.0 expression:
/Stats/Stat
[Data/@Name='Entity'
and
not(Data[@Name='Entity'] = following-sibling::Stat/Data[@Name = 'Entity'])
]
/Data[@Name='Entity']
XSLT - based verification:
<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>
when this transformation is applied on the following XML document (produced by correcting the non-well-formed provided text):
<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>
the above XPath expression is evaluated and the selected nodes are copied to the output:
<Data Name="Entity">second</Data>
<Data Name="Entity">third</Data>
<Data Name="Entity">first</Data>
Note: If you just need the text nodes ("first", "second" and "third"), just use this single XPath expression:
/Stats/Stat
[Data/@Name='Entity'
and
not(Data[@Name='Entity'] = following-sibling::Stat/Data[@Name = 'Entity'])
]
/Data[@Name='Entity']
/text()
回答2:
You need to say which version of XPath. In XPath 2.0, it's trivial:
distinct-values(/Stats/Stat/Data/@Name)
来源:https://stackoverflow.com/questions/10532657/get-distinct-values-within-specific-attributes