2010-12-16 42 views

Respuesta

7

Creo que esto tiene algo de qué hacer con el procesamiento de estilo comprensión push vs. pull de comparar únicamente xsl:for-each o xsl:template match="...". A menudo se ven programadores de otra disciplina usando un montón de xsl:if, xsl:choose y bucles for cuando el problema podría haberse resuelto de una manera más elegante XSLTish.

Pero a la pregunta:En mi opinión, si se tiene en cuenta el uso de xsl:for-each en lugar de procesar los datos con xsl:apply-templates necesita volver a pensar. Hay casos en los que un bucle for es adecuado en XSLT, pero cada vez que una plantilla coincida haría lo mismo, las plantillas son el camino a seguir. En mi experiencia, generalmente puedes hacer más xsl:for-each con un xsl:apply-templates en su lugar.

Algunos de los beneficios como lo veo de la utilización de plantillas que emparejan en un bucle para son:

  • Las hojas de estilo son más fáciles de mantener y extender especialmente si los cambios de datos fuente.
  • Como menciona @chiborg, las plantillas se pueden reutilizar ya que no están integradas en una plantilla específica. Junto con xsl:next-match en XSLT 2.0, puede encadenar plantillas juntas de maneras potentes.
  • No tiene que imitar el comportamiento ya incorporado en todos los procesadores XSLT, es decir; use xsl:apply-templates y deje que el procesador trabaje para usted.
  • Además, me resulta más fácil de entender y depurar una hoja de estilo de estilo push. Si divide su plantilla de hoja pequeñas plantillas que hacen una o varias cosas y escribe patrones de coincidencia específicos, es fácil ver qué plantilla está haciendo qué y rastrear el origen del problema.
+0

Estoy de acuerdo con que es fácil ver qué sucede dentro de cada plantilla, pero es más difícil ver qué plantilla se invocará, en qué orden (con apply-templates). – LarsH

+0

@LarsH: Eso es lo que usas la depuración maravillosa de Oxygens para ...;) –

+0

Tienes razón, yo sí :-) y es un salvavidas a veces. Pero la depuración solo puede ayudar si tiene los datos de entrada XML en la mano ... y solo puede ayudar para esa instancia de datos en particular. Mientras que si puede leer la hoja de estilo con comprensión, puede sacar muchas más conclusiones sobre lo que puede y lo que no puede suceder, independientemente de la entrada particular, en comparación con cuando no puede leer la hoja de estilo con comprensión. – LarsH

1

for-each solo se puede utilizar dentro de un lugar en su plantilla. Las plantillas se pueden reutilizar con diferentes llamadas a apply-templates. La mayoría de las veces uso plantillas en lugar de for-each debido a la flexibilidad añadida.

3

Realmente no importa, pero es posible que desee pensar en ello por la siguiente pulgar de reglas que he encontrado:

  • Si el código depende del contexto posición (posición()), ponerlo en un <xsl:for-each>.
  • Si el código depende del contexto nodo (.o cualquier ruta de ubicación), ponlo en una plantilla coincidente.
  • De lo contrario, utilice una plantilla con nombre.

de referencia y leer más en: http://www.jenitennison.com/blog/node/9

1

Estos son para completar diferentes instrucciones XSLT.

Más que un estilo push vs. pull, esto es más como iteración vs. recursión.

xsl:for-each es una instrucción de iterador con todos los beneficios y restricciones de la iteración en un paradigma declarativo sin estado: un buen procesador no debe contaminar la pila de llamadas.

xsl:apply-templates es una instrucción de recursión general. General en el sentido de que es más poderoso que xsl:call-template: "arroja" los nodos seleccionados al mecanismo de coincidencia de patrones, una verdadera "invocación dinámica de funciones".

5

Tanto la 'para-cada' y 'plantilla' son utilizado para recuperar los nodos de XML en el XSL. Pero lo que es la diferencia entre ellos en básicamente

Estas son algunas de las diferencias más importantes:

  1. xsl:apply-templates es mucho más rica y más profunda que xsl:for-each, incluso simplemente porque no sé qué código se aplicará en los nodos de la selección - en el caso general este código será diferente para diferentes nodos de la n ode-list.

  2. El código que se aplicará manera se pueden escribirse después de los xsl:apply template s fue escrito por y personas que no conocen el autor original.

implementación de funciones de orden superior (HOF) en XSLT El FXSL library 's no sería posible si XSLT no tenía la instrucción <xsl:apply-templates>.

Resumen: Las plantillas y la instrucción <xsl:apply-templates> es cómo XSLT implementa y se ocupa de polimorfismo.

Referencia: Ver toda esta discusión: http://www.stylusstudio.com/xsllist/200411/post60540.html

+0

En "este hilo completo", Dimitre no escribe nada que no esté ya en esta página de SO. – Roland

+0

@Roland, "Todo este hilo" se cita aquí como referencia que combina las respuestas de algunas personas inteligentes. No hay ninguna declaración en esta respuesta que diga que uno encontraría algo diferente. –

10

por lo general de acuerdo con las otras respuestas, pero he de decir que en mi experiencia, una hoja de estilo escrito con xsl:for-each puede ser mucho más fácil de leer, entienda y mantenga que uno que confía fuertemente xsl:apply-templates ... Especialmente xsl:apply-templates con una selección implícita (o una selección muy genérica como select="node()").

¿Por qué? Porque es muy fácil ver qué hará cada uno. Con apply-templates, en esencia tiene que (a) conocer todas las posibles entradas XML (lo que será más fácil si tiene un esquema, pero aún tiene que digerir el esquema, y ​​muchas veces no tiene un esquema). , especialmente para datos XML intermedios transitorios enviados en una etapa de una canalización, e incluso si tiene un esquema, su marco de desarrollo (como un ESB o CMS) puede no darle una forma de validar su XML en cada punto de sus canalizaciones. Por lo tanto, si entran datos no válidos, no se le notificará de inmediato), para que pueda predecir qué tipos de nodos se seleccionarán (p. Ej., Hijos del nodo contextual); y (b) observe cada plantilla en la hoja de estilo para ver qué plantilla coincide con los nodos con mayor prioridad (y la última en orden de documentos).El orden de procesamiento también puede omitir todos los archivos, o sobre diferentes archivos (importados o incluidos). Esto puede hacer que sea muy difícil "ver" lo que está pasando.

Mientras que con un para cada uno, usted sabe exactamente qué código se creará una instancia: el código dentro de cada uno. Y dado que para-cada uno requiere una expresión de selección explícita, es más probable que tenga un campo más estrecho para adivinar con respecto a qué nodos se pueden emparejar.

Ahora no estoy negando que apply-templates sea mucho más poderoso y flexible que for-each. Ese es exactamente el punto: las construcciones que son más potentes y flexibles, también son más difíciles de restringir, comprender y depurar (y evitar agujeros de seguridad). Es el Rule of Least Power: "Los lenguajes potentes (o en este caso, los constructos) inhiben la reutilización de la información". (Also discussed here.)

Cuando utiliza plantillas-aplicar, cada plantilla es más modular y, por lo tanto, más reutilizable en sí misma, pero la hoja de estilos es más compleja y la interacción entre plantillas es menos predecible . Cuando usa para cada uno, el flujo de procesamiento es fácil de predecir y ver.

Con <xsl:apply-templates />, (o con <xsl:for-each select="node()"/>), cuando la estructura del XML de entrada cambia, el comportamiento de la hoja de estilos cambia, sin la revisión del desarrollador. Que esto sea bueno o malo depende de cuánta previsión ha puesto en su hoja de estilo y de cuánta buena comunicación existe entre el desarrollador del esquema XML y el desarrollador de la hoja de estilos (que puede ser la misma persona o pertenecer a diferentes organizaciones).

Para mí, es una decisión. Si tiene XML orientado a documentos, como HTML, donde muchos tipos de elementos realmente pueden tener muchos tipos diferentes de hijos, en una jerarquía de profundidad arbitraria, y el procesamiento de un tipo de elemento dado no depende muy a menudo de su contexto. , luego aplicar plantillas es absolutamente esencial. Por otro lado, si tiene XML "orientado a datos", con una estructura predecible, donde no siempre tiene el mismo tipo de elemento que significa lo mismo en diferentes contextos, para cada uno puede ser mucho más sencillo de leer y depurar (y por lo tanto escribir correctamente y rápidamente).

+1

+1 Creo que esta es una evaluación más equilibrada que la respuesta aceptada – PandaWood

+0

@PandaWood, gracias. – LarsH

1

Un uso de for-each No he mencionado: se puede utilizar para cambiar el nodo de contexto a otro documento. Lo he usado para transformar XML de datos a un formulario de entrada HTML. La plantilla que coincidía con un campo de datos contenía un for-each que seleccionaba un solo nodo: el xs:element en el XSD que describía el campo de datos a transformar.

Usando la descripción en el XSD, un campo de datos podría transformarse en un grupo de botones de opción, un cuadro desplegable o una entrada de texto simple y simple. Sin for-each no pude leer los dos documentos al mismo tiempo.

En general, prefiero las plantillas a juego. Encuentro que corresponde a la noción de una sola transformación aplicada a la vez mejor que para cada uno de los nodos, luego la siguiente, luego la siguiente, etc. Pero esa es una preferencia personal, por supuesto.

+0

+1. Establecer el nodo de contexto es un uso importante de 'for-each' - buen punto. Y a menudo, esa es la forma más clara y concisa de establecer el nodo de contexto. Sin embargo, * usted * también puede usar 'apply-templates' para hacer lo mismo. En otras palabras, no creo que sea cierto que no puedas leer dos documentos al mismo tiempo sin usar 'for-each'. Recuerde que 'apply-templates' puede usar modos y pasar parámetros. – LarsH