2010-05-20 28 views
10

¿Cómo puedo seleccionar solo elementos distintos para el documento XML con XPATH? He intentado utilizar la función 'valores distintivos' pero no funcionó por algún motivo ...¿Cómo seleccionar valores distintos del documento XML usando XPATH?

El XML es similar al siguientes:

<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> 

Así que lo que quiero llegar es la lista de los niños distintas de todo el producto elements.In el ejemplo dado que sería - tamaño, precio, calificación, año Mi XPath era algo así como: distinta -valores (catálogo/producto/*)

+0

función de valores distintivos utilizada para un solo valor y contenido en línea o contenido de atributo. ¿A qué se refiere exactamente por niños distintos? ¿Son diferentes nombres de elementos como tamaño, precio, clasificación, no los valores? – Myra

+0

Lo siento, sí, exactamente. Quiero obtener la lista de todos los nombres de elementos de niños distintos – Alex

+0

¡Es posible que XPath no tenga nombres distintos! – Myra

Respuesta

14

En XPath 2.0:

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

En XPath 1.0 esto no se puede producir con una sola expresión XPath.

Usando 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> 

Cuando se aplica esta transformación en el documento XML proporcionado, el resultado deseado se produce:

size price rating year 

A más eficiente XSLT 1.0 transformación , utilizando las claves:

<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() está disponible en XPath 2 .0. ¿Estás usando eso?

Si distinct-values() no está disponible, la forma estándar de obtener valores distintos es usar not(@result = preceding:: @result) para obtener el resultado único @result. Le dará la primera ocurrencia solamente.

+1

No estoy seguro de qué versión de XPATH tengo :) ¿Cómo puedo obtener información al respecto? – Alex

+0

Eso solo funcionaría si la lista se ordena en su resultado – Hazaart

2

Usted necesita los valores distintos de los nombres de los elementos - algo así como:

distinct-values($catalog/product/*/name(.)) 
Cuestiones relacionadas