Algunas cosas que harán que la comprensión de las respuestas que obtenga más fácil:
En primer lugar, nodos y elementos no son la misma cosa. Los elementos son nodos, pero los nodos no son necesariamente elementos. A menudo encuentras personas que usan los términos indistintamente. En realidad, hay cuatro tipos de nodos en XML: elementos, nodos de texto, instrucciones de procesamiento y comentarios. (Los atributos no son realmente nodos, a los que llegaré en un segundo.)
En XSLT, la raíz de un documento XML no es su elemento de nivel superior; la raíz es una abstracción que realmente no existe. El elemento de nivel superior es un elemento secundario de la raíz.Por ejemplo, aquí hay un documento XML bien formado cuya raíz tiene cinco nodos secundarios, incluyendo el elemento de nivel superior:
<?xml-stylesheet href="mystyle.css" type="text/css"?>
<!-- this is a perfectly legitimate XML document -->
<top_level_element/>
Cinco? Parece que solo hay tres. Creo que te dejaré descubrir cuáles son los otros dos tú mismo. Sugerencia: en realidad podría haber siete nodos en ese ejemplo.
La expresión XPath /
encuentra la raíz del documento, no el elemento de nivel superior. En el caso anterior, para buscar el elemento de nivel superior, usaría /top_level_element
o /*
. (Siempre es seguro usar /*
para encontrar el elemento de nivel superior, ya que la raíz del documento debe tener un elemento único secundario.)
Armados con ese conocimiento, veamos qué hace apply-templates
. Básicamente realiza un proceso de dos pasos: Primero, construye un conjunto de nodos. Luego, y para cada uno, encuentra una plantilla coincidente (de entre las plantillas en el archivo XSLT) y aplica la plantilla a ella. Como observó en uno de sus comentarios, es conceptualmente muy similar a un ciclo.
El atributo select
se utiliza en el primer paso. Proporciona una expresión XPath que se usa para construir el conjunto de nodos al que va a aplicar plantillas. Si no se proporciona el atributo select
, la lista que crea es todos secundarios del nodo de contexto. (El "nodo de contexto" es el nodo al que se está aplicando la plantilla actual).
El atributo match
en los elementos template
se usa en el segundo paso. El procesador de hojas de estilo encuentra todas las plantillas cuyo atributo match
coincide con el nodo al que intenta aplicar las plantillas. Si encuentra más de uno, selecciona el más específico que pueda, p. dado estas plantillas:
<xsl:template match="*"/>
<xsl:template match="foo"/>
<xsl:template match="foo[bar]"/>
un elemento de foo
con un elemento de bar
niño será igualada por la tercera, un elemento de foo
sin bar
será igualado por el segundo, y un elemento de baz
será igualada por la primera. (El método actual que utiliza XSLT se define here, en la práctica, he estado usando XSLT durante casi una década y nunca una vez he necesitado saber específicamente cómo funciona, aunque es interesante.)
Si no encuentra una coincidencia, se utilizará la plantilla por defecto incorporado para el tipo de nodo - básicamente, se puede asumir que cualquier transformación XSLT contiene implícitamente estas plantillas:
<xsl:template match="*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
<xsl:copy/>
</xsl:template>
<xsl:template match="processing-instruction() | comment() | @*"/>
armado con todo este conocimiento, ahora puede comprender la transformación de identidad:
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
Eso coincide con cualquier nodo o atributo (tenga en cuenta que los atributos no son nodos, por lo que se necesita @*
), lo copia y luego aplica plantillas a todos sus nodos y atributos secundarios. (Solo la raíz del documento y los elementos tendrán nodos secundarios, y solo los elementos tendrán atributos). Dado que es la única plantilla en la transformación y coincide con todos los nodos y atributos, se aplica a todos los nodos y atributos secundarios. Por lo tanto, copia todo en el árbol fuente al árbol de salida.
Si se agrega esta plantilla para la identificación transformar:
<xsl:template match="foo"/>
ahora tiene una transformación que copias cada nodo en el árbol de fuentes exceptofoo
elementos - que segundo encaja foo
elementos (el primero también lo hace, pero dado que el segundo atributo match
es más específico, es el que XSLT elige) y no hace nada con ellos.
Teniendo en cuenta todo esto, las respuestas a sus preguntas específicas:
<xsl:apply-templates>
aplica las plantillas a los hijos del nodo de contexto.
Los nodos coincidentes no se "devuelven" en el paso 1; el procesador XSLT encuentra una plantilla para cada uno y la aplica.
En este ejemplo, el nodo de contexto es la raíz del documento, un nodo abstracto que el elemento de nivel superior y cualquier comentario o instrucciones de procesamiento fuera de él son los secundarios de.
La declaración "Los atributos no son realmente nodos" es incorrecta. Los atributos son nodos, pero los atributos no son elementos secundarios del elemento. Para más detalles, mira mi respuesta a continuación. ejecuta solo plantillas para niños (axis child: :) pero no para atributos (axis attribute: :) –