xslt - transformar - ¿Cuáles son las diferencias entre ''call-template'' y ''apply-templates'' en XSL?
xsl excel (4)
Soy nuevo en XSLT, así que estoy un poco confundido acerca de las dos etiquetas,
<xsl:apply-templates name="nodes">
y
<xsl:call-template select="nodes">
Entonces, ¿puedes enumerar la diferencia entre ellos?
La funcionalidad es de hecho similar (aparte de la semántica de llamada, donde call-template
requiere un atributo de name
y una plantilla de nombres correspondiente).
Sin embargo, el analizador no se ejecutará de la misma manera.
Desde MSDN :
A diferencia de
<xsl:apply-templates>
,<xsl:call-template>
no cambia el nodo actual o la lista de nodos actual.
Para agregar a la buena respuesta por @Tomalak:
Aquí hay algunas diferencias no mencionadas e importantes :
xsl:apply-templates
es mucho más rico y profundo quexsl:call-templates
e incluso dexsl:for-each
, simplemente porque no sabemos qué código se aplicará a los nodos de la selección; en el caso general esto el código será diferente para diferentes nodos de la lista de nodos.El código que se aplicará puede escribirse mucho después de que se haya escrito la
xsl:apply template
y de personas que no conozcan al autor original.
La implementación de la biblioteca FXSL de funciones de orden superior (HOF) en XSLT no sería posible si XSLT no tuviera la instrucción <xsl:apply-templates>
.
Resumen : las plantillas y la instrucción <xsl:apply-templates>
es la forma en que XSLT implementa y trata el polimorfismo.
Referencia : Ver todo este hilo: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html
<xsl:call-template>
es un equivalente cercano a llamar a una función en un lenguaje de programación tradicional.
Puede definir funciones en XSLT, como esta simple que genera una cadena.
<xsl:template name="dosomething">
<xsl:text>A function that does something</xsl:text>
</xsl:template>
Esta función se puede llamar a través de <xsl:call-template name="dosomething">
.
<xsl:apply-templates>
es un poco diferente y es el verdadero poder de XSLT: toma cualquier número de nodos XML (lo que sea que defina en el atributo select
), los itera ( esto es importante: apply-templates funciona como un bucle! ) y encuentra plantillas coincidentes para ellos:
<!-- sample XML snippet -->
<xml>
<foo /><bar /><baz />
</xml>
<!-- sample XSLT snippet -->
<xsl:template match="xml">
<xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>
<xsl:template match="foo"> <!-- will be called once -->
<xsl:text>foo element encountered</xsl:text>
</xsl:template>
<xsl:template match="*"> <!-- will be called twice -->
<xsl:text>other element countered</xsl:text>
</xsl:template>
De esta forma, cede un poco de control al procesador XSLT; no decide a dónde va el flujo del programa, sino que el procesador busca la coincidencia más adecuada para el nodo que está procesando actualmente.
Si varias plantillas pueden coincidir con un nodo, gana el que tenga la expresión de coincidencia más específica. Si existe más de una plantilla coincidente con la misma especificidad, la última declarada gana.
Puede concentrarse más en desarrollar plantillas y necesita menos tiempo para hacer "plomería". Sus programas serán más potentes y modularizados, anidados menos profundamente y más rápidos (a medida que los procesadores XSLT se optimizan para la coincidencia de plantillas).
Un concepto para comprender con XSLT es el del "nodo actual". Con <xsl:apply-templates>
el nodo actual se mueve con cada iteración, mientras que <xsl:call-template>
no cambia el nodo actual. Es decir, el .
dentro de una plantilla llamada se refiere al mismo nodo que el .
en la plantilla de llamada. Este no es el caso con apply-templates.
Esta es la diferencia básica. Hay otros aspectos de las plantillas que afectan su comportamiento: su mode
y priority
, el hecho de que las plantillas pueden tener tanto un name
como una match
. También tiene un impacto si la plantilla ha sido importada ( <xsl:import>
) o no. Estos son usos avanzados y puede tratarlos cuando llegue allí.
xsl:apply-templates
generalmente se usa (pero no necesariamente) para procesar todo o un subconjunto de elementos secundarios del nodo actual con todas las plantillas aplicables. Esto es compatible con la recursividad de la aplicación XSLT que se corresponde con la recursividad (posible) del XML procesado.
xsl:call-template
por otro lado, se parece mucho más a una llamada de función normal. Ejecuta exactamente una plantilla (nombrada), generalmente con uno o más parámetros.
Así que utilizo xsl:apply-templates
si quiero interceptar el procesamiento de un nodo interesante y (generalmente) inyectar algo en el flujo de salida. Un ejemplo típico (simplificado) sería
<xsl:template match="foo">
<bar>
<xsl:apply-templates/>
</bar>
</xsl:template>
mientras que con xsl:call-template
normalmente resuelvo problemas como agregar el texto de algunos subnodos, transformar conjuntos de nodos en texto u otros conjuntos de nodos y cosas por el estilo, cualquier cosa para la que escribirías una función especializada y reutilizable.
Editar:
Como comentario adicional a su texto de pregunta específico:
<xsl:call-template name="nodes"/>
Esto llama a una plantilla que se llama ''nodos'':
<xsl:template name="nodes">...</xsl:template>
Esta es una semántica diferente de:
<xsl:apply-templates select="nodes"/>
... que aplica todas las plantillas a todos los hijos de su nodo XML actual cuyo nombre es ''nodos''.