Salta el contingut

XSLT

Qué és XSLT?

XSLT (eXtensible Stylesheet Language Transformations) és un llenguatge per transformar documents XML en altres formats: HTML, un altre XML, text pla, CSV, etc.

XML + XSLT → Processador XSLT → HTML / XML / Text

XSLT és en si mateix un document XML. El processador XSLT llegeix el document XML d'entrada i aplica les plantilles del full d'estil XSLT per generar la sortida.

Estructura d'un full XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- Definir el tipus de sortida -->
    <xsl:output method="html" encoding="UTF-8" indent="yes"/>

    <!-- Plantilla que captura l'arrel del document -->
    <xsl:template match="/">
        <!-- contingut generat... -->
    </xsl:template>

    <!-- Altres plantilles... -->

</xsl:stylesheet>

Associar un XSLT a un XML

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="biblioteca.xsl"?>
<biblioteca>
    <!-- ... -->
</biblioteca>

Elements fonamentals XSLT

xsl:template

Defineix una plantilla que s'aplica als nodes que coincideixen amb el patró:

<!-- Plantilla per a l'arrel -->
<xsl:template match="/">
    <html>
        <body>
            <xsl:apply-templates select="biblioteca/llibre"/>
        </body>
    </html>
</xsl:template>

<!-- Plantilla per a cada element 'llibre' -->
<xsl:template match="llibre">
    <div class="llibre">
        <h2><xsl:value-of select="titol"/></h2>
    </div>
</xsl:template>

xsl:value-of

Extreu el valor de text d'un node:

<xsl:value-of select="titol"/>
<xsl:value-of select="@isbn"/>
<xsl:value-of select="concat(autor/nom, ' ', autor/cognom)"/>

xsl:for-each

Itera sobre un conjunt de nodes:

<xsl:template match="/">
    <table>
        <tr><th>Títol</th><th>Autor</th><th>Any</th></tr>
        <xsl:for-each select="biblioteca/llibre">
            <tr>
                <td><xsl:value-of select="titol"/></td>
                <td><xsl:value-of select="autor/cognom"/></td>
                <td><xsl:value-of select="any"/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

xsl:sort

Ordena nodes dins xsl:for-each o xsl:apply-templates:

<xsl:for-each select="biblioteca/llibre">
    <xsl:sort select="any" data-type="number" order="ascending"/>
    <xsl:sort select="titol" order="ascending"/>
    <!-- ... -->
</xsl:for-each>

xsl:if

Condició simple (sense else):

<xsl:if test="preu &lt; 20">
    <span class="oferta">OFERTA</span>
</xsl:if>

<xsl:if test="@idioma = 'ca'">
    <span class="badge">Català</span>
</xsl:if>

Caràcters especials en expressions

En XSLT, dins dels atributs test i select, els caràcters < i > s'han d'escapar: &lt; i &gt;.

xsl:choose / xsl:when / xsl:otherwise

Condicions múltiples (equivalent a switch/if-elif-else):

<xsl:choose>
    <xsl:when test="preu &lt; 10">
        <span class="barat">Barat</span>
    </xsl:when>
    <xsl:when test="preu &lt; 25">
        <span class="mig">Preu mitjà</span>
    </xsl:when>
    <xsl:otherwise>
        <span class="car">Car</span>
    </xsl:otherwise>
</xsl:choose>

Exemple complet: XML → HTML

biblioteca.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="biblioteca.xsl"?>
<biblioteca>
    <llibre isbn="L001" idioma="ca">
        <titol>Tirant lo Blanc</titol>
        <autor><nom>Joanot</nom><cognom>Martorell</cognom></autor>
        <any>1490</any>
        <preu>25.90</preu>
    </llibre>
    <llibre isbn="L002" idioma="es">
        <titol>Don Quijote</titol>
        <autor><nom>Miguel</nom><cognom>Cervantes</cognom></autor>
        <any>1605</any>
        <preu>18.50</preu>
    </llibre>
</biblioteca>

biblioteca.xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="html" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <html lang="ca">
        <head>
            <title>Biblioteca</title>
            <style>
                table { border-collapse: collapse; width: 100%; }
                th, td { border: 1px solid #ccc; padding: 8px; }
                th { background: #00695c; color: white; }
                .ca { color: #00695c; font-weight: bold; }
            </style>
        </head>
        <body>
            <h1>Catàleg de la Biblioteca</h1>
            <p>Total de llibres: <xsl:value-of select="count(//llibre)"/></p>
            <table>
                <tr>
                    <th>ISBN</th>
                    <th>Títol</th>
                    <th>Autor</th>
                    <th>Any</th>
                    <th>Preu</th>
                    <th>Idioma</th>
                </tr>
                <xsl:for-each select="biblioteca/llibre">
                    <xsl:sort select="any" data-type="number"/>
                    <tr>
                        <td><xsl:value-of select="@isbn"/></td>
                        <td><xsl:value-of select="titol"/></td>
                        <td>
                            <xsl:value-of select="concat(autor/nom, ' ', autor/cognom)"/>
                        </td>
                        <td><xsl:value-of select="any"/></td>
                        <td><xsl:value-of select="preu"/> </td>
                        <td>
                            <xsl:choose>
                                <xsl:when test="@idioma = 'ca'">
                                    <span class="ca">Català</span>
                                </xsl:when>
                                <xsl:when test="@idioma = 'es'">Castellà</xsl:when>
                                <xsl:when test="@idioma = 'en'">Anglès</xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="@idioma"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

Transformació XML → XML

XSLT també pot generar un nou XML (p. ex., filtrar o reformatar dades):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <!-- Exportar només els llibres en català -->
    <xsl:template match="/">
        <biblioteca_ca>
            <xsl:for-each select="//llibre[@idioma='ca']">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </biblioteca_ca>
    </xsl:template>

</xsl:stylesheet>

Execució per línia de comandes

# Saxon (recomanat — suporta XSLT 2.0/3.0)
java -jar saxon-he.jar -s:biblioteca.xml -xsl:biblioteca.xsl -o:sortida.html

# xsltproc (Linux/Mac — suporta XSLT 1.0)
xsltproc biblioteca.xsl biblioteca.xml > sortida.html

Miniactivitat AC03741

Crea un XSLT que transformi el teu institut.xml (RA1) en una pàgina HTML amb: taula de cicles i mòduls, nombre d'hores per mòdul resaltat en vermell si és >100h, ordena els mòduls per codi alfabèticament.