2011-11-08 20 views
5

Asumamos que tenemos este sencillo xml ...primer nodo hijo en XSLT utilizando Local-name()

<books> 
    <book> 
     <author/> 
     <title/> 
    </book> 
    <book> 
     <author/> 
     <title/> 
    </book> 
</books> 

estoy usando este XPath para obtener los elementos de la primera instancia libro.

//books[1]/* 

Devoluciones

<author/> 
<title/> 

y que funciona muy bien, pero tengo que conseguir que funcione usando local-name(). He intentado lo siguiente, pero ninguno de estos funciona ...

//*[local-name()='books']/* 

Esto devuelve la repetición de elementos de autor y título y no buena, lo único que los necesitan desde el primer hijo

//*[local-name()='books'][0]/* 

esto no devolver cualquier cosa

Básicamente, quiero crear un archivo CSV, por lo que la primera línea del resultado será un encabezado que enumere los nombres de los atributos del libro seguidos de los valores de datos arbitrarios. Solo necesito que la parte del encabezado funcione.

author,title 
john,The End is Near 
sally,Looking for Answers 
+2

Su consulta '// books [1]/*' debe devolver dos elementos de libro, no un autor y un elemento de título. Entonces hay algo de confusión en alguna parte. –

+0

No, solo devuelve el primero con mi transformador Xalan 1.0 XSLT – raffian

+0

Sí, eso fue malo en el OP, estoy usando [1], thx para la información – user646584

Respuesta

9

La expresión de ruta que dicen que funciona para

//books[1]/* 

genera una lista de todos los nodos secundarios de la primera aparición (y sólo en este caso) de cualquier <libros> nodo. Debido a que, en sus datos, la única ocurrencia de <libros> está en la raíz, que es la misma que

/books/* 

que devuelve dos <libro> nodos, y por lo que se equivocan al decir que se devuelve sólo una nodo.

Es difícil saber lo que necesita, como si siempre está solicitando local-name al nodo raíz, entonces no es necesario conocer su nombre y puede acceder a ella con sólo /*, por lo que querría simplemente

/*/*[1] 

Sin embargo, para acceder al primer nodo hijo de un <libros> nodo en cualquier parte del documento que iba a escribir

//*[local-name()='books']/*[1] 

usted debe tener cuidado de limitar su contexto tanto como p posible, ya que al iniciar la expresión XPath con // forzará una búsqueda de todo el documento, lo cual es inútil y lleva mucho tiempo si el nodo en cuestión siempre está en la raíz.

+0

Consulte mis ediciones anteriores en la publicación original para obtener más información sobre lo que intento lograr, disculpe la falta de detalles adicionales. Intenté usar/*/* [1], estoy imprimiendo "autor, título" dos veces, solo necesito imprimir una vez. – raffian

+0

Esto funcionó, gracias – raffian

12

Este es un FAQ - el operador XPath [] tiene mayor prioridad (prioridad) que la // pseudo-operador.

Así:

//someElemName[1] 

selecciona cada elemento llamado someElemName que es el primer hijo de su padre - y, según el documento XML, puede haber más de uno de tales elementos.

Para cambiar esto, se deben usar corchetes.

Uso:

(//*[local-name() = 'book'])[1]/* 

También tenga: En las posiciones XPath son, no se basa 0-1 basado en.

basado en XSLT verificación:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "(//*[local-name() = 'book'])[1]/*"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica esta transformación en el siguiente documento XML:

<books> 
    <book num="1"> 
     <author num="1"/> 
     <title num="1"/> 
    </book> 
    <book num="2"> 
     <author num="2"/> 
     <title num="2"/> 
    </book> 
</books> 

los nodos deseados se seleccionan y se copia a la salida :

<author num="1"/> 
<title num="1"/> 
+0

@RaffiM: ¿Te fue útil mi respuesta? –

+0

fue para mí, gracias por la respuesta Dimitre – user151496

+0

@ user1916182, De nada. –

0

Tengo que encontrar las mismas preocupaciones. Lo resolví de la siguiente manera:

//*[local-name()='MYNODENAME' and position()=X] 

Que tengas un buen día.

Cuestiones relacionadas