Вот пример:
<root>
<item type='test'>A</item>
<item type='test'>B</item>
<item type='test'>C</item>
<item type='test'>A</item>
<item type='other'>A</item>
<item type='test'>B</item>
<item type='other'>D</item>
<item type=''>A</item>
</root>
И XPath:
//preceding::item/preceding::item[not(.=preceding-sibling::item)]/text()
Результаты: РЕДАКТИРОВАНИЕ B C D
: Поскольку mousio прокомментировал, что это не получает последний объект в списке, если это - единственное время, это появляется. При принятии во внимание этого и FГ «комментарий anor, вот лучшее решение:
/root/item[not(.=preceding-sibling::item)]
Разве Вы не пропускающий ссылку на 'описательное' право после предыдущего значения? Некоторая вещь как следующее:
/doc/class/person/descriptive[(@name='age')][not(value=preceding-sibling::descriptive[@name='age']/value)]/value
(Не протестировали его)
Вот версия Muenchian ответа BQ с помощью его данных:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="text"/>
<xsl:key name="item-by-value" match="item" use="."/>
<xsl:template match="/">
<xsl:apply-templates select="/root/item"/>
</xsl:template>
<xsl:template match="item">
<xsl:if test="generate-id() = generate-id(key('item-by-value', normalize-space(.)))">
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="text()">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
Это преобразование дает
А
B
C
D
key()
поиск выше в шаблоне для item
возвраты набор узлов, содержащий весь эти item
элементы с тем же строковым значением как узел контекста. generate-id()
, как гарантируют, генерируют тот же идентификатор для данного узла во время единственной передачи через документ. key()
вызов. The Muenchian method uses keys to create a unique list of items from the node set. For your data, the key would look like this:
<!-- Set the name to whatever you want -->
<xsl:key name="PeopleAges" match="/doc/class/person/descriptive[@name = 'age']/value" use="." />
From there, I would personally use xsl:apply-templates
but you can use the following select
attribute in other places:
<!-- you can change `apply-templates` to: `copy-of` or `for-each`. -->
<xsl:apply-templates select="/doc/class/person/descriptive[@name = 'age']/value[count(. | key('PeopleAges', .)[1]) = 1]" />
The accompanying match for the above is much simpler:
<xsl:template match="person/descriptive[@name = 'age']/value">
<strong>Age: </strong><xsl:value-of select="." />
</xsl:template>