2010-05-20 7 views
10

Как я могу выбрать только отдельные элементы для XML-документа с помощью XPATH? Я пытался использовать функцию «отдельных значений», но по какой-то причине она не работала.Как выбрать различные значения из документа XML с помощью XPATH?

XML похож на следующее:

<catalog> 

<product> 
<size>12</size> 
<price>1000</price> 
<rating>1</rating> 
</product> 

<product> 
<size>10</size> 
<price>1000</price> 
<rating>1</rating> 
<year>2010</year> 
</product> 

</catalog> 

Так что я хочу, чтобы это список отдельных детей все продукта elements.In в данном примере это будет - размер, цена, рейтинг, год Моим был XPath-то вроде: отчетливое -значения (каталог/продукт/*)

+0

Функция отдельных значений, используемая только для одного значения для встроенного контента или содержимого атрибута. Что вы подразумеваете под разными дочерними элементами? Это разные имена элементов, такие как размер, цена, рейтинг, а не значения? – Myra

+0

Извините, но я хочу получить список всех имен дочерних элементов – Alex

+0

. Вы не можете захватывать различные имена XPath! – Myra

ответ

14

В XPath 2.0:

distinct-values(/*/*/*/name(.)) 

В XPath 1.0 это не может быть получен с помощью одного выражения XPath.

Использование XSLT 1.0:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:template match="/"> 
    <xsl:for-each select= 
    "/*/*/*[not(../following::*/* 
         [not(name() = name(current()))] 
       ) 
      ]"> 
    <xsl:value-of select="concat(name(), ' ')"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на прилагаемом документе XML, полезный результат, полученный:

size price rating year 

Более эффективный XSLT 1.0 Преобразование , с использованием ключей:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:key name="kpchildByName" 
    match="product/*" use="name()"/> 

<xsl:template match="/"> 
    <xsl:for-each select= 
    "/*/*/* 
     [generate-id() 
     = 
      generate-id(key('kpchildByName', name())[1]) 
      ]"> 
    <xsl:value-of select="concat(name(), ' ')"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
3

distinct-values() доступен в XPath 2,0. Вы используете это?

Если distinct-values() недоступен, стандартный способ получения различных значений - использовать not(@result = preceding:: @result) для получения уникального @result. Это даст вам первое появление.

+1

Я не уверен, какая версия XPATH у меня есть :) Как я могу узнать об этом? – Alex

+0

Это будет работать, только если список отсортирован по вашему результату – Hazaart

2

Вам нужны различные значения имен элементов - что-то вроде:

distinct-values($catalog/product/*/name(.)) 
Смежные вопросы