Получить различные значения в определенных атрибутах
У меня есть следующий код 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 ответа
Используйте это выражение 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>
Примечание. Если вам просто нужны текстовые узлы ("первый", "второй" и "третий"), просто используйте это единственное выражение XPath:
/Stats/Stat
[Data/@Name='Entity'
and
not(Data[@Name='Entity'] = following-sibling::Stat/Data[@Name = 'Entity'])
]
/Data[@Name='Entity']
/text()
Вы должны сказать, какая версия XPath. В XPath 2.0 это тривиально:
distinct-values(/Stats/Stat/Data/@Name)