Robots y modelos

Notas sobre pruebas, modelado y aventuras en Java y Android

Posts Tagged ‘saxon

Saxon y XSLT2

leave a comment »

Últimamente estoy trabajando bastante con XLST 2 y XPath 2.0, empleando la biblioteca Saxon (que le da tropecientas vueltas a Xalan, y lo digo por experiencia). La verdad es que se pueden hacer cosas ahora que de otra forma me serían muy complicadas en XSLT 1.0, aunque tiene sus pequeños detalles molestos. El último día me tiré varias horas rascándome la cabeza de por qué una secuencia de elementos que creaba con xsl:for-each de XSLT acababa creando nuevos nodos en vez de utilizar los existentes, haciendo que fallara la prueba de identidad “. is $nodo” (sólo devuelve true si se trata exactamente de la misma copia del mismo nodo).

Es decir, si por ejemplo tengo este bucle que recorre una serie de elementos del árbol XML:

<xsl:for-each select="a|b|c">
  <xsl:sequence select="."/>
</xsl:for-each>

Si queremos recoger los resultados en una variable, uno pensaría hacerlo así:

<xsl:variable name="x">
  <xsl:for-each select="a|b|c">
    <xsl:sequence select="."/>
  </xsl:for-each>
</xsl:variable>

Sin embargo, esto no funciona como es esperado: los a, b y c dentro de x son copias de los originales. Tras mucho rebuscar por San Google, no encontré nada, pero el estándar XSLT 2.0 incluye en su punto 5.7 lo siguiente:

The sequence may be used to construct the content of a new element or document node. This happens when the sequence constructor appears as the content of a literal result element, or of one of the instructions xsl:copy, xsl:element, xsl:document, xsl:result-document, or xsl:message. It also happens when the sequence constructor is contained in one of the elements xsl:variable, xsl:param, or xsl:with-param, when this instruction has no as attribute. For details, see 5.7.1 Constructing Complex Content.

Es decir, que con añadir una declaración de tipo de secuencia a la variable sirve:

<xsl:variable name="x" as="item()*">
  <xsl:for-each select="a|b|c">
    <xsl:sequence select="."/>
  </xsl:for-each>
</xsl:variable>

Para los que no lo sepan, “item()*” indica que tenemos cero o más (“*”) elementos de cualquier tipo (“item()”). Podríamos concretarlo más si nos preocuparan temas de tipado o quisiéramos forzar una cierta conversión (como de entero a cadena), pero en este caso no hace falta.

Dejo esto apuntado por si alguna otra persona tiene el mismo problema que yo (que no lo creo, pero bueno :-D).

Written by bluezio

6 de septiembre de 2008 at 8:31

Publicado en Uncategorized

Tagged with , , ,

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 260 seguidores