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.
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 < 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: < i >.
xsl:choose / xsl:when / xsl:otherwise
Condicions múltiples (equivalent a switch/if-elif-else):
<xsl:choose>
<xsl:when test="preu < 10">
<span class="barat">Barat</span>
</xsl:when>
<xsl:when test="preu < 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.