transformar online example xslt

online - xslt sap



Diferencia entre: child:: node() y child::* (2)

Acabo de escribir un XSLT que no funcionó al principio.

Tuve que cambiar el nombre de todos los hijos de <Recordset> a <C> :

<?xml version="1.0" encoding="utf-8"?> <Record> <Recordset> <company>102</company> <store>1801</store> .... </Recordset> <Recordset> .... </Recordset> </Record>

Usé el siguiente XSLT:

<xsl:template match="Record/Recordset/child::*"> <xsl:element name="C"> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template>

Funciona y cambia el nombre de todos los elementos secundarios de <Recordset> a <C> . Pero primero mi coincidencia en la plantilla se veía así:

<xsl:template match="Record/Recordset/child::node()">

Mi idea era que cada elemento secundario de <Recordset> es un nodo, por lo que node() sería apropiado. Funcionó también pero insertó una <C/> extra para cada niño.

¿Cuál es la diferencia entre child::node() y child::* ?


Para ampliar la respuesta de lwburk, si su XML se ve así:

<A> <B/> <C/> <D/> </A>

Entonces, el elemento A tiene 7 nodos secundarios; tres de ellos son elementos, cuatro son nodos de texto. La expresión child::node() coincide con los 7, mientras que child::* solo coincide con los elementos.


child::node() coincide con cualquier nodo que no sea un nodo de atributo, nodo de espacio de nombres o nodo de documento. Eso significa que no coincide con las instrucciones de procesamiento, los comentarios y los nodos de texto.

child::* coincide solo con elementos.

Ver la sección 5.5.3 de la especificación:

El patrón node () coincide con todos los nodos seleccionados por la expresión raíz (.) // (child-or-top :: node ()), es decir, todos los elementos, texto, comentario y nodos de instrucción de procesamiento, independientemente de que tener un padre No coincide con los nodos de atributo o de espacio de nombres porque la expresión no selecciona los nodos que utilizan el atributo o los ejes del espacio de nombres. No coincide con los nodos de documento porque, por razones de compatibilidad con versiones anteriores, el eje secundario o superior no coincide con un nodo de documento.

Actualización: la respuesta de Michael inspiró la siguiente hoja de estilo. Úselo para probar los tipos de nodos a medida que se procesan:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/|node()"> <xsl:call-template name="type" /> <xsl:text> [ </xsl:text> <xsl:value-of select="." /> <xsl:text>&#10;</xsl:text> <xsl:apply-templates select="node()" /> <xsl:text> ] </xsl:text> </xsl:template> <xsl:template name="type"> <xsl:choose> <xsl:when test="count(.|/)=1"> <xsl:text>Root</xsl:text> </xsl:when> <xsl:when test="self::*"> <xsl:text>Element </xsl:text> <xsl:value-of select="name()" /> </xsl:when> <xsl:when test="self::text()"> <xsl:text>Text</xsl:text> </xsl:when> <xsl:when test="self::comment()"> <xsl:text>Comment</xsl:text> </xsl:when> <xsl:when test="self::processing-instruction()"> <xsl:text>PI</xsl:text> </xsl:when> <xsl:when test="count(.|../@*)=count(../@*)"> <xsl:text>Attribute</xsl:text> </xsl:when> </xsl:choose> </xsl:template> </xsl:stylesheet>

Modifique lo que coincide / seleccionado para probar otros patrones. Por ejemplo, la siguiente entrada:

<A attr="test" other="val"> <B/> <C>some value</C> <!-- a comment --> <D/> </A>

Produce el siguiente resultado:

Root [ some value Element A [ some value Text [ ] Element B [ ] Text [ ] Element C [ some value Text [ some value ] ] Text [ ] Comment [ a comment ] Text [ ] Element D [ ] Text [ ] ] ]

Un agradecimiento especial a esta página por iniciarme en las pruebas de tipo de nodo. (Es especialmente apropiado que una de las respuestas de Michael de hace más de seis años aparezca allí también).