2011-04-29 25 views
9

Tengo consulta básica. He estado usando xsl: template y uso call tempate para hacer llamadas recursivas a la plantilla. Veo xsl: function, que también tiene la posibilidad de realizar llamadas a funciones recursivas, como llamadas a plantillas recursivas y lograr lo mismo. Cuándo se debe usar xsl: function y cuándo se debe usar xsl: template. No estoy seguro de cuál es la diferencia entre los dos y cuándo deberían usarse. ¿Cuáles son sus características especiales de cada uno de ellos? ¿Puede alguien ayudarme a entender esto mejor?XSL llamada recursiva - xsl: funciones vs xsl: plantilla con plantilla de llamada

+0

Buena pregunta, +1. Ver mi respuesta para explicación, comparación y recomendación. –

Respuesta

1

Encontré la respuesta de Dimitre - http://www.stylusstudio.com/xsllist/200811/post00400.html - útil.

Beneficios del uso de <xsl:function/>:

  1. Compuestabilidad.

  2. Se ve muy bien en una expresión que lo usa como parámetro, como valor de retorno o como una aplicación parcial .

  3. Legibilidad (compacidad) y facilidad de mantenimiento.

  4. Más acoplamiento débil (no depende de un nodo de contexto implícita)

  5. se puede hacer referencia en una expresión XPath

Deficiencias:

  1. parámetros son identificado solo por posición (no por nombre)

  2. Puede ser impuro (puede tener un efecto secundario, como la creación de un nuevo nodo (s)) y con sólo mirar a una expresión referencia a esta función la gente puede no entender que tiene un lado efecto. Sin embargo, esta posibilidad de confusión se puede eliminar si se utiliza el nombre apropiado .

Tiendo siempre a usar <xsl:function/>. En los casos cuando la función crea nuevo nodo (s), sigo la convención de comenzando su nombre local con la cadena "make", como en makePerson().

2

Conceptualmente xsl:apply-templates es un mapa con una función polimórfica expresada para todas las reglas que ha declarado. xsl:function declara una función "normal" que puede usar en cualquier otra instrucción o declaración que acepte expresiones XPath. La instrucción xsl:call-template "invoca" una plantilla con un nombre particular (de alguna manera podría pensar en esto como una función).

Debido a esto, existen diferencias en cuanto a cómo el contexto de evaluación involucra a cada uno: xsl:apply-templates define una nueva lista de contexto a partir de la cual se toma el nodo de contexto, así como la posición de proximidad; xsl:function no tiene nodo de contexto definido (es un error confiar en él); xsl:call-template no cambia el contexto de la evaluación.

Otra diferencia evidente es su relación con la salida: tanto xsl:apply-templates como xsl:call-template como instrucciones XSLT generan su secuencia construida; xsl:function como parte de una expresión XPath no es así.

+0

@Alejandro: Encuentro dos afirmaciones en su respuesta que son problemáticas (no exactamente verdaderas). 1) "' xsl: function' no tiene un nodo de contexto definido (es un error confiar en él); "Es más exacto decir que el procesador XSLT debe señalar un error si se encuentra una expresión relativa de XPath en el cuerpo de la función. 2) "xsl: función como parte de una expresión XPath no lo hace. (Muestra una secuencia construida)". Esto no es verdad. Una 'xsl: function' puede crear nodos y devolverlos - Yo uso esta técnica. Sí, una 'xsl: function' puede tener efectos secundarios. –

+0

@Dimitre: From http://www.w3.org/TR/xslt20/#stylesheet-functions _ "Dentro del cuerpo de una función de hoja de estilo, el enfoque está inicialmente indefinido, lo que significa que cualquier intento de referencia al elemento del contexto, la posición del contexto, o el tamaño del contexto es un error dinámico no recuperable. "_ Sobre dos: no es la función que está dando salida al árbol de resultados, sino la instrucción XSLT. Acerca de los efectos secundarios, bueno, podría estar en disputa: incluso las funciones que construyen nuevos nodos como resultado construirán el mismo resultado para el mismo argumento, además de que podría no tener la misma identidad de nodo. –

+0

@Dimitre: del tema: parece que hubo una importante retag que cambió todas las etiquetas 'xpathengines' para' xpath' incluso cambiando la atribución para la edición (si me etiquetaron con 'xpathengines' ahora dice que lo he etiquetado con 'xpath'). Siga la discusión en http://meta.stackexchange.com/questions/89005/what-did-happen-with-xpathengines-and-xqueryengines-tags –

6

Ésta es hace how I replied to a similar question casi 3 años:

Beneficios del uso de <xsl:function/>:

  1. Compuestabilidad.

  2. Se ve muy bien en una expresión que lo usa como parámetro, como valor de retorno o como una aplicación parcial .

  3. Legibilidad (compacidad) y facilidad de mantenimiento.

  4. Más acoplamiento débil (no depende de un nodo de contexto implícita)

  5. se puede hacer referencia en una expresión XPath

Deficiencias:

  1. parámetros son identificado solo por posición (no por nombre)

  2. Puede ser impuro (puede tener un efecto secundario, como la creación de un nuevo nodo (s)) y con sólo mirar a una expresión referencia a esta función la gente puede no entender que tiene un lado efecto. Sin embargo, esta posibilidad de confusión se puede eliminar si se utiliza el nombre apropiado .

Tiendo siempre a usar <xsl:function/>. En los casos cuando la función crea nuevo nodo (s), sigo la convención de comenzando su nombre local con la cadena "make", como en makePerson().

sólo puedo añadir a esto:

Siempre que sea posible el uso <xsl:function>.

En XPath 3.0 las funciones son un tipo de datos de primera clase del lenguaje (también conocido como HOF - Higher-Order Functions). Se pueden pasar como parámetros o devolver como resultado a/desde otras funciones.

Este es un avance increíblemente poderoso de usar plantillas con nombre.

0
Templates are useful when you have the requirement to store the results of each recursion into a variable as a attribute (at the end of each recursion before calling the next). 

**Example:** 

    <xsl:variable name="test"> 
    <record> 
     <xsl:call-template name="templateRecursion"> 
       <xsl:with-param name="xyz" select="xyz"/> 
     </xsl:call-template> 
    <record> 
    </xsl:variable> 

**templateRecursion:** 

    <xsl:template name="templateRecursion"> 

    <!-- Do processing --> 
    <xsl:attribute name="" value="" 

    </xsl:template> 

So, the variable test will have 

    <record> 
    <attribute_name="" value=""/> 
     . 
     . 
    </record>