viernes, 13 de mayo de 2011

fn:document-uri() en XSLT 1.0

El significado del acrónimo AJAX es "JavaScript asíncrono y XML". El abuso de esta técnica ha llegado a su utilización también para el caso de acceso "sincronizado" a recursos XML.

Un simple documento XML junto a una hoja de estilo en lenguaje XSLT sería suficiente para el caso de acceso "sincronizado". La dificultad reside en la imposibilidad de pasar parámetros a las hojas de estilo sino es a través de (nuevamente!) JavaScript. La inexistencia de una interfaz standard entre navegadores para la simple invocación de una transformación también se colude para impedir la adopción de esta técnica.

Todo sería más fácil si pudieramos acceder a la URI del recurso. Es de notar de que a pesar de existir esta información en el Infoset, no es hasta la versión XSLT 2.0 (ausente de todos los navegadores) que tenemos las funciones fn:document-uri() y fn:base-uri().

He aquí una técnica completamente standard (aunque no soportada por todos los parsers de XML): declarar una entidad externa no parseada con una URI relativa al documento y luego obtener esta URI a través de la función unparsed-entity-uri() de XPath 1.0

Revision: En la versión anterior de esta entrada se deslizó un error en relación a las URI relativas: de acuerdo a la especificación RFC 3986:

The most frequent examples of same-document references are relative references that are empty or include only the number sign ("#") separator followed by a fragment identifier.

Conforme a esto se ha corregido el error y pedido disculpas a los desarrolladores de Webkit por denunciar equivocadamente un bug.

Ejemplo:


<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<!DOCTYPE test [<!ENTITY uri SYSTEM "" NDATA uri>]>
<test/>



<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="unparsed-entity-uri('uri')"/>
</xsl:template>
</xsl:stylesheet>


Aquí les dejo un ejemplo vivo para que vean todas las posibilidades detrás de esta técnica. Actualmente sólo los navegadores Internet Explorer (con algunas excepciones de las que aún no he podido rastrear el origen, probablemente la versión de la librería MSXSL), Opera, Chrome y Safari soportan la declaración de entidades. Si les parece adecuado pueden solicitar el soporte en Firefox.