xsl transformar transformación programacion online manejo lenguajes freeformater xslt xslt-1.0 xslt-2.0

transformar - XSLT xsl: secuencia. Para que sirve..?



transformar xml a xslt (4)

Sé que la siguiente pregunta es un poco de principiantes, pero necesito tu ayuda para entender un concepto básico.

Primero me gustaría decir que soy programador de XSLT durante 3 años y, sin embargo, hay algunas cosas nuevas y bastante básicas que he estado aprendiendo aquí. Nunca lo supe. (En mi trabajo, cualquiera aprende a programar solo, no hay curso involucrado).

Mi pregunta es: ¿Cuál es el uso de xsl:sequence ?

He estado usando xsl:copy-of para copiar node como es, xsl:apply-templates para modificar los nodos que seleccioné y value-of para texto simple.

Nunca tuve la necesidad de usar xsl:sequence . Agradecería que alguien me mostrara un ejemplo del uso de la xsl:sequence que es preferible o que no se puede lograr sin los que anoté anteriormente.

Una cosa más, he leído sobre la definición de xsl:sequence por supuesto, pero no pude deducir cómo es útil.


Bueno, para devolver un valor de un cierto tipo, utiliza xsl:sequence como xsl:value-of pesar de que su nombre siempre crea un nodo de texto (desde XSLT 1.0). Entonces en un cuerpo de función que usas

<xsl:sequence select="42"/>

para devolver un valor xs:integer , usarías

<xsl:sequence select="''foo''"/>

para devolver un valor xs:string y

<xsl:sequence select="xs:date(''2013-01-16'')"/>

para devolver un xs:date valor de xs:date y así sucesivamente. Por supuesto, también puede devolver secuencias con, por ejemplo, <xsl:sequence select="1, 2, 3"/> .

No me gustaría crear un nodo de texto o incluso un nodo de elemento en estos casos, en mi opinión, ya que es ineficiente.

Esa es mi opinión, con el nuevo sistema de tipo basado en esquemas de XSLT y XPath 2.0 se necesita una forma de devolver o pasar valores de estos tipos y se necesitaba una nueva construcción.

[editar] Michael Kay dice en su "referencia del programador XSLT 2.0 y XPath 2.0" sobre xsl:sequence : "Esta instrucción de aspecto inocente introducida en XSLT 2.0 tiene efectos de largo alcance sobre la capacidad del lenguaje XSLT, porque significa que las instrucciones XSLT y los constructores de secuencia (y por lo tanto las funciones y las plantillas) pueden devolver cualquier valor permitido por el modelo de datos XPath. Sin él, las instrucciones XSLT solo podrían usarse para crear nuevos nodos en un árbol de resultados, pero también pueden devolver valores atómicos y referencias a nodos existentes ".


El caso de uso más común para xsl: sequence es devolver un resultado de xsl: function.

<xsl:function name="f:get-customers"> <xsl:sequence select="$input-doc//customer"/> </xsl:function>

Pero también puede ser útil en otros contextos, por ejemplo

<xsl:variable name="x" as="element()*"> <xsl:choose> <xsl:when test="$something"> <xsl:sequence select="//customer"/> </xsl:when> <xsl:otherwise> <xsl:sequence select="//supplier"/> </xsl:otherwise> </xsl:choose> </xsl:variable>

La clave aquí es que devuelve referencias a los nodos originales, no hace nuevas copias.


Otro uso es crear una etiqueta solo si tiene un hijo. Se requiere un ejemplo:

<a> <b>node b</b> <c>node c</c> </a>

En algún lugar de tu XSLT:

<xsl:variable name="foo"> <xsl:if select="b"><d>Got a "b" node</d></xsl:if> <xsl:if select="c"><d>Got a "c" node</d></xsl:if> </xsl:variable> <xsl:if test="$foo/node()"> <wrapper><xsl:sequence select="$foo"/></wrapper> </xsl:if>

Puede ver la demostración aquí: http://xsltransform.net/eiZQaFz

Es mucho mejor que probar cada etiqueta como esta:

<xsl:if test="a|b">...</xsl:if>

Porque terminarías editándolo en dos lugares. Además, la velocidad de procesamiento dependerá de las etiquetas que tenga en su interfaz. Si es el último de su prueba, el motor probará la presencia de todos antes. Como $ foo / node () es un modismo para "¿hay algún elemento secundario?", El motor puede optimizarlo. Al hacerlo, alivias la vida de todos.


<xsl:sequence> en un valor atómico (o secuencia de valores atómicos) es lo mismo que <xsl:copy-of> ambos simplemente devuelven una copia de su entrada. La diferencia viene cuando consideras los nodos.

Si $ n es un nodo de elemento único, por ejemplo, como se define por algo así como

<xsl:variable name="n" select="/html"/>

Entonces

<xsl:copy-of select="$n"/>

Devuelve una copia del nodo, tiene el mismo nombre y estructura hija, pero es un nuevo nodo con una nueva identidad (y sin padre).

<xsl:sequence select="$n"/>

Devuelve el nodo $ n, el nodo devuelto tiene el mismo padre que $ n y es igual a él por el operador is Xpath.

La diferencia está enmascarada casi por completo en el uso de plantillas tradicionales (estilo XSLT 1) ya que nunca se obtiene acceso al resultado de ninguna de las operaciones; el resultado del constructor se copia implícitamente en el árbol de salida, por lo que el hecho de que xsl:sequence no la copia está enmascarada

<xsl:template match="a"> <x> <xsl:sequence select="$n"/> </x> </xsl:template>

es lo mismo que

<xsl:template match="a"> <x> <xsl:copy-of select="$n"/> </x> </xsl:template>

Ambos crean un nuevo nodo de elemento y copian el resultado del contenido como secundarios del nuevo nodo x .

Sin embargo, la diferencia se ve rápidamente si usa funciones.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="data:,f"> <xsl:variable name="s"> <x>hello</x> </xsl:variable> <xsl:template name="main"> :: :: <xsl:value-of select="$s/x is f:s($s/x)"/> :: <xsl:value-of select="$s/x is f:c($s/x)"/> :: :: <xsl:value-of select="count(f:s($s/x)/..)"/> :: <xsl:value-of select="count(f:c($s/x)/..)"/> :: </xsl:template> <xsl:function name="f:s"> <xsl:param name="x"/> <xsl:sequence select="$x"/> </xsl:function> <xsl:function name="f:c"> <xsl:param name="x"/> <xsl:copy-of select="$x"/> </xsl:function> </xsl:stylesheet>

Produce

$ saxon9 -it main seq.xsl <?xml version="1.0" encoding="UTF-8"?> :: :: true :: false :: :: 1 :: 0 ::

Aquí los resultados de xsl:sequence y xsl:copy-of son radicalmente diferentes.