Robots y modelos

Notas sobre pruebas, modelado y aventuras en Java y Android

Posts Tagged ‘xml

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).

Anuncios

Written by bluezio

6 de septiembre de 2008 at 8:31

Publicado en Uncategorized

Tagged with , , ,

Módulo YAML/JSON->YAXML y Manual de Usuario

leave a comment »

Esta semana he estado escribiendo el Manual de Usuario (está entre los documentos del proyecto de la forja), y empecé el Manual del Desarrollador. Por lo pronto ya tengo las instrucciones de compilación, pero aún queda mucho por escribir. Más que nada lo hago porque la gracia de XMLEye está precisamente en que se escriban muchos tipos de documento para él.

Se me ocurrió que sería bueno tener un ejemplo sencillo en dicho manual, ya que definitivamente ACL2::Procesador no serviría como “ejemplo sencillo”: 6000 líneas aproximadamente de código Perl orientado a objetos, fábricas y demás, y sin contar la infraestructura necesaria para que todo funcione como un módulo Perl estándar.

Dicho y hecho: se me ocurrió que YAML podría ser un buen candidato, siempre que pueda escapar la ira de sus usuarios por ensuciarlo convirtiéndolo a XML :-D. Así se pueden usar más tecnologías XML sobre él, como XML Schema o XSLT.

Así que he creado un módulo Perl basado sobre YAML::Syck (un binding Perl de la biblioteca Syck de serialización) que convierte YAML a XML, e incluye una hoja XSLT que devuelve el XML así creado a YAML. Integra pruebas de unidad para asegurarse de que no se producen pérdidas de información en el proceso YAML->XML->YAML. Todo se ha hecho siguiendo las directrices de un binding experimental de YAML para XML, YAXML, disponible en http://www.yaml.org/xml.html.

Además, tiene sus propias hojas de usuario y descriptor de tipo para preprocesamiento y visualización para XMLEye, con lo que nos saltamos algunas de las limitaciones de XML a la hora de visualizar, como no poder tener elementos como “Pepito el de mi pueblo”, que sí son claves de tabla hash válidos en YAML, o nombrar como “Elemento 0” a los elementos de una lista. La hoja de visualización es una especialización de la hoja XML que añade elementos de los elementos con atributo alias a sus anchor correspondientes.

Se encuentra también en mi repositorio Debian, junto con una versión más reciente de XMLEye que corrige algunos fallos de los que me he dado cuenta desarrollando este ejemplo, dentro del paquete libyaxml-reverse-perl. Puede usarse como un módulo más, o a través del guión yaml2xml que incluye el paquete.

Ah, y de paso: este módulo (y XMLEye por lo tanto) también acepta documentos JSON, ya que dicho estándar no es más que un subconjunto de YAML. Si alguien conoce un vocabulario estándar basado en YAML o JSON, que me lo comente y veré si me puedo montar una especialización de las hojas de usuario para YAXML.

Al final creo que no he conseguido un ejemplo sencillo de preprocesador, pero por lo menos las hojas de visualización y preprocesado sí que son bastante sencillas :-D.

Written by bluezio

9 de marzo de 2008 at 21:07

Publicado en Uncategorized

Tagged with , , , , , ,