XSLT (I): Hojas de Estilos para Transformación

Hace cuatro años que comencé a utilizar esta tecnología para el desarrollo web. Al principio como una forma de realizar una vista aislada del código base de la aplicación web, después como un metalenguaje más simple que el HTML y más enfocado a la presentación de formularios y datos específicos (semántica) en lugar de presentación.

Por último, hace poco, lo he visto muy útil para crear metalenguajes que simplifiquen cosas como VoiceXML. Este sistema y/o lenguaje que se basa en el uso de etiquetas XML, así como el uso de plugins a través de la etiqueta object (al igual que en HTML) y ECMAScript (o JavaScript) para agregar aún más dinamismo (y complejidad), supuso un reto.

El trabajo de XSLT, en todos estos escenarios fue la confección de un lenguaje intermedio (un metalenguaje) que se pudiese traducir de forma inmediata al lenguaje destinatario o esperado por el navegador o cliente que lo solicitara.

Formato básico de XSLT

El lenguaje XSLT se basa en un formato XML fijo que consta de una cabecera de definición de etiquetas propias para XSL, tras la cual se puede continuar usando las propias etiquetas para conformar el documento de estilos específico. La cabecera básica suele tener esta forma:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        version="1.0">
...
</xsl:stylesheet>

Una etiqueta que debe de contener, de forma aconsejada, este formato anterior presentado es xsl:output. La etiqueta xsl:output se encarga de prefijar e indicar el formato de salida que se generará por parte de la hoja de estilos.

Por ejemplo, si el formato de salida fuese un documento XHTML, la etiqueta de xsl:output podría ser como la que se indica a continuación:

<xsl:output method="xml" 
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />

En caso de querer usar una salida en texto plano, el método sería text y no habría que indicar doctype-system.

Las plantillas

Lo siguiente, es hacer los match específicos con la etiqueta xsl:template. Cada documento origen XML está formado, obviamente, de etiquetas. Para comenzar la transformación, debe de hacerse un recorrido por las etiquetas base y buscar, de entre las etiquetas xsl:template, las que casen con la etiqueta que se está navegando en cada momento.

Por ejemplo, si tenemos el documento XML origen:

<comidas>
    <plato>
        <nombre>Salmorejo</nombre>
        <origen>Córdoba</origen>
    </plato>
    <plato>
        <nombre>Callos</nombre>
        <origen>Madrid</origen>
    </plato>
</comidas>

La etiqueta base es comidas, y esta ya contiene todo el documento en sí. Podríamos definir un XSLT que, al encontrar la etiqueta base, escribiese las etiquetas de cabecera de un tipo HTML básico:

<xsl:template match="comidas">
    <html>
        <head>
            <title>Comidas</title>
        </head>
        <body>
            <h1>Comidas</h1>
            <hr />
            <table>
                <tr>
                    <th>Nombre</th>
                    <th>Origen</th>
                </tr>
                <xsl:apply -templates select="*" />
            </table>
        </body>
    </html>
</xsl:template>

Esto hace que la etiqueta base comidas se cambie por todo el código HTML escrito. Así mismo, como un código XML no se puede dejar sin cerrar, en la parte del cuerpo, donde se quiera insertar más contenido, habrá que indicarle a XSLT que hay que buscar más templates que hagan match ya con las etiquetas que haya dentro de comidas.

Usando el texto de las etiquetas

Por ahora hemos cambiado unas etiquetas por otras, ahora vamos a seguir haciendo lo mismo, pero tomando la información que está contenida dentro de la etiqueta, completando el código XSLT visto antes:

<xsl:template match="plato">
    <tr>
        <td><xsl:value -of select="nombre" /></td>
        <td><xsl:value -of select="origen" /></td>
    </tr>
</xsl:template>

Generando el código desde PHP

Para esto tendremos que tener instalado el módulo de XML y XSL en PHP. En phpinfo debe de verse activa la extensión DOM/XML y xsl.

Con esto activo, ya solo nos queda escribir algo como lo siguiente:

# cargamos el documento XML origen
$xml = DOMDocument::load("fichero.xml");
 
# cargamos la hoja de estilos de transformación (XSLT)
$xsl = DOMDocument::load("fichero.xsl");
 
# procesamos e imprimimos
$pro = new XSLTProcessor();
$pro->importStyleSheet($xsl);
print $pro->transformToXML($xml);

Conclusiones

Esto es un primer vistazo a XSLT, he querido que se vea de forma simple el uso de las etiquetas base, pero aún queda mucho por ver, ya que no se ha hablado ni de XPath, ni de sus funciones, así como de la potencia de etiquetas como xsl:if, xsl:choose o xsl:for-each. Lo veremos todo más adelante.