2012-06-30 20 views
7

¿Cómo obtener la posición del nodo principal en el documento completo utilizando xpath?Buscar posición del nodo principal utilizando xpath

decir que tienen la siguiente xml:

<catalog> 
    <cd> 
    <title>Empire Burlesque</title> 
    <artist>Bob Dylan</artist> 
    <country>USA</country> 
    <company>Columbia</company> 
    <price>10.90</price> 
    <year>1985</year> 
    </cd> 
    <cd> 
    <title>Hide your heart</title> 
    <artist>Bonnie Tyler</artist> 
    <country>UK</country> 
    <company>CBS Records</company> 
    <price>9.90</price> 
    <year>1988</year> 
    </cd> 
</catalog> 

y tengo un XSLT para convertirlo en HTML, que es el siguiente (sólo fragmento de código):

<xsl:template match="/"> 
<html> 
    <body> 
    <xsl:apply-templates/> 
    </body> 
    </html> 
</xsl:template> 

<xsl:template match="cd"> 
    <p> 
    <xsl:number format="1. "/><br/> 
    <xsl:apply-templates select="title"/> 
    <xsl:apply-templates select="artist"/> 
    </p> 
</xsl:template> 

<xsl:template match="title"> 
    <xsl:number format="1" select="????" /><br/> 
    Title: <span style="color:#ff0000"> 
    <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

¿Qué debo escribir en el lugar de ???? para obtener la posición de la etiqueta padre cd en el documento. He intentado muchas expresiones pero parece que nada funciona. Puede ser que lo estoy haciendo completamente mal.

  1. <xsl:number format="1" select="catalog/cd/preceding-sibling::..[position()]" />
  2. <xsl:number format="1" select="./parent::..[position()]" /><br/>
  3. <xsl:value-of select="count(cd/preceding-sibling::*)+1" /><br/>

estoy interpretando como segundo eje padre de selección del nodo actual y luego digo la posición del padre del nodo actual. ¿Por qué no está funcionando? ¿Cuál es la forma correcta de hacer esto?

FYI: Espero que el código imprima la posición de la etiqueta de cd principal del procesamiento actual de la etiqueta del título uder.

Por favor, alguien me puede decir cómo hacerlo.

Respuesta

16
count(../preceding-sibling::cd) + 1 

Usted puede run it here (nota quité el otro número que estaba dando salida, sólo para mayor claridad).

Estaba en la línea correcta, pero recuerde que los predicados se usan solo para filtrar nodos, no para devolver información. Entonces:

../*[position()] 

... dice de manera efectiva "encuéntrame el padre que tiene una posición". Devuelve el nodo, no la posición en sí. El predicado es solo un filtro.

En cualquier caso hay trampas con el uso de position(), y se puede usar para devolver la posición del nodo actual, el contexto solamente - no otro nodo.

+0

Gracias una tonelada hombre, ahora que era tonto de mi parte no probar eso. Gracias de nuevo :) – Harshdeep

+0

Solo una cosa más puede explicar la expresión "count (../ previous-sibling :: cd) + 1" como lo hizo para "position()". Usé su solución y funcionó muy bien, pero no puedo entender por qué no "count (cd/previous-sibling :: ..) + 1" – Harshdeep

+2

Recuerde que las plantillas XSLT operan desde la perspectiva del nodo de contexto actual. En la plantilla correspondiente, el nodo de contexto es el título. Por lo tanto, 'count (cd ...)' no encontrará ningún nodo porque no hay nodos secundarios de 'title' llamados' cd' (de hecho, 'title' no tiene nodos secundarios de ningún nombre). 'cd' es el padre de' title', no es su hijo, por lo tanto, tenemos que subir un nivel. – Utkanos

1
<xsl:number format="1" select="????" /> 

¿Qué debo escribir en el lugar de ???? para obtener la posición de la etiqueta de cd principal en el documento.

En primer lugar, la instrucción XSLT anterior es sintácticamente incorrecto - la instrucción <xsl:number> no (no) tener un atributoselect.

Uso: Respuesta

<xsl:number format="1" count="cd" /> 
+0

Así que también se puede hacer usando xsl: number. Gracias por la info. ¿Puedes darnos más información sobre cómo funciona esto? – Harshdeep

+0

@Harshdeep: Puedes aprender mejor "cómo funciona esto" haciendo clic en el enlace (sí, el color azul de '' en la respuesta significa que se trata de un enlace que se puede hacer clic). Para ver los resultados del uso de esta instrucción, cópiela y péguelo en su código. –

+0

Hice clic en el enlace antes de preguntarle pero la documentación de w3 es tan voluminosa que no me parece muy 'legible'. Pero lo investigaremos ahora para una mejor comprensión. – Harshdeep

3

de Utkanos funciona bien, pero mi experiencia es que, cuando el documento XML es grande, esto podría conducir a problemas de rendimiento.

En este caso, simplemente podría pasar la posición del elemento primario en un parámetro.

<xsl:template match="/"> 
<html> 
    <body> 
    <xsl:apply-templates/> 
    </body> 
    </html> 
</xsl:template> 

<xsl:template match="cd"> 
    <p> 
    <xsl:number format="1. "/><br/> 
    <xsl:apply-templates select="title"> 
     <xsl:with-param name="parent_position" select="position()"/> <!-- Send here --> 
    </xsl:apply-templates> 
    <xsl:apply-templates select="artist"/> 
    </p> 
</xsl:template> 

<xsl:template match="title"> 
    <xsl:param name="parent_position"/> <!-- Receive here --> 
    <xsl:number format="1" select="$parent_position"/><br/> 
    Title: <span style="color:#ff0000"> 
    <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

resultado:

<html xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><body> 
    <p>1. <br>1<br> 
    Title: <span style="color:#ff0000">Empire Burlesque</span><br>Bob Dylan</p> 
    <p>2. <br>1<br> 
    Title: <span style="color:#ff0000">Hide your heart</span><br>Bonnie Tyler</p> 
</body></html> 
Cuestiones relacionadas