XSLT
Trasformazioni XSL
Ing. Luca Sabatucci
XSLT
Uno dei vantaggi principali nell'utilizzo
dell'Extensible Markup Language è la facilità con
cui si possono trasformare i documenti di dati
XML in altri formati e strutture, come i file
HyperText Markup Language (HTML).
Lo strumento utilizzato per definire queste
trasformazioni è denominato Extensible
Stylesheet Language Transformations (XSLT).
Foglio di stile
Un insieme di regole che permettono di
trasformare un documento in un altro
documento si chiama foglio di stile
Un foglio di stile si definisce mediante l’XSL
XSL è una applicazione XML
Processo di trasformazione
La trasformazione avviene tramite un processore
chiamato elaboratore XSLT
Applicazioni pratiche
Web
Un documento XML può essere trasformato in una
pagina HTML in modo da essere visualizzato tramite
browser Web
XSL-FO
Un documento può essere trasformato in formato
FO (Formatting Object) che rappresenta una
applicazione di formattazione precisa dei documenti
narrativi
Namespace XSL
XSL è una applicazione XML
XSL definisce un proprio DTD e un Namespace
L’URL da usare per il namespace è
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
Il namespace viene generalmente associato al
prefisso ‘xsl’
xsl:stylesheet
L’elemento radice di un documento XSL è
xsl:stylesheet
All’interno dell’elemento xsl:stylesheet si
mettono le regole di trasformazione
Il più semplice foglio di stile XSL prevede che
non vi siano regole di trasformazione
Catalogo persone
<catalogo>
<persona>
<nome>Luca</nome>
<cognome>Sabatucci</cognome>
<origine>
<data_di_nascita>
<giorno>16</giorno>
<mese>2</mese>
<anno>1976</anno>
</data_di_nascita>
<luogo_di_nascita>Palermo</luogo_di_nascita>
</origine>
<professione da="Luglio 2002">Ingegnere</professione>
</persona>
<persona>
<nome>Mario</nome>
<cognome>Rossi</cognome>
<origine>
<data_di_nascita>
<giorno>4</giorno>
<mese>7</mese>
<anno>1982</anno>
…
La più semplice trasformazione
Se si trasforma il file XML catalogo persone con
un foglio di stile vuoto, come quello mostrato di
seguito…
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
Output
Si ottiene l’output mostrato di seguito:
LucaSabatucci1621976PalermoIngegnere
MarioRossi471982Milano
Foglio di stile vuoto
In assenza di regole la trasformazione è la
seguente:
Viene prelevato il testo interno agli elementi del
documento di input
Viene quindi riprodotto il contenuto ma non il
markup.
In questo caso il risultato non è un documento XML
Modelli e regole
Per controllare il modo in cui viene generato
l’output in base all’input bisogna aggiungere dei
modelli all’interno del foglio di stile
Ogni modello è rappresentato da un elemento
xsl:template, dotato di un attributo match
xsl:template definisce una regola di trasformazione
match identifica il tipo di input che attiva la regola
esempio: persona “Una persona”
Esempio
Di seguito viene mostrata la regola
corrispondente a:
persona “Una persona”
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="persona">Una persona</xsl:template>
</xsl:stylesheet>
Output:
Una personaUna persona
Associamo uno stile HTML
E’ possibile fare in modo che l’output sia un
documento XML ben formato
<xsl:stylesheet version="1.0" xmlns:xsl=“…">
<xsl:template match="persona">
<p>Una persona</p>
</xsl:template>
</xsl:stylesheet>
Output
Output XML
<p>Una persona</p><p>Una persona</p>
Output HTML (Internet Explorer)
Una persona
Una persona
Valore di un elemento
L’elemento xsl:value-of permette di selezionare
il contenuto di un elemento di input e inserirlo
come output
xsl:value-of si può trovare soltanto all’interno di
un elemento xsl:template
L’attributo select serve a selezionare il valore che
deve essere prelevato
Esempio
Di seguito viene riportato un esempio di
elemento xsl:value-of:
<xsl:stylesheet version="1.0" xmlns:xsl=“…">
<xsl:template match="persona">
<p>Una persona: <xsl:value-of select="nome"/></p>
</xsl:template>
</xsl:stylesheet>
Output
Output XML
<p>Una persona: Luca</p><p>Una persona: Mario</p>
Output HTML (Internet Explorer)
Una persona: Luca
Una persona: Mario
select
Nell’esempio mostrato l’attributo select di
xsl:value-of era impostato come di seguito:
select="nome“
Dove “nome” è l’attributo del quale si vuole estrarre
l’informazione.
Più in generale il valore di select deve essere una
espressione XPath
XPath sarà argomento delle prossime lezioni.
Applicazione forzata di modelli
L’utilizzo della regola xsl:apply-templates
permette di stabilire quali modelli devono essere
applicati e in che ordine
xsl:apply-templates possiede un attributo select
che specifica una regola di tipo xsl:template
Esempio
<xsl:stylesheet version="1.0" xmlns:xsl=“…">
<xsl:template match="persona">
<p>
<xsl:apply-templates select="cognome"/>
<xsl:apply-templates select="nome"/>
</p>
</xsl:template>
<xsl:template match="nome">
Nome: <xsl:value-of select="text()"/><br/>
</xsl:template>
<xsl:template match="cognome">
Cognome: <xsl:value-of select="text()"/><br/>
</xsl:template>
</xsl:stylesheet>
select
A differenza del primo esempio in cui l’attributo
select di xsl:value-of era impostato come:
select="nome“
In questo esempio si ha:
select="text()”
Dove “text()” è una espressione XPath che sta ad
indicare che dell’elemento corrente (nell’esempio si
trattava del nome o del cognome) deve essere
prelevato il testo in esso contenuto.
Output
Output XML
<p>
Cognome: Sabatucci<br/>
Nome: Luca<br/>
</p>
<p>
Cognome: Rossi<br/>
Nome: Mario<br/>
</p>
Output
Output HTML (Internet Explorer)
Cognome: Sabatucci
Nome: Luca
Cognome: Rossi
Nome: Mario
Intestazione HTML
<xsl:template match="catalogo">
<html>
<head>
<title>Catalogo persone</title>
</head>
<body>
<xsl:apply-templates select="persona"/>
</body>
</html>
</xsl:template>
Output XML
<html>
<head>
<title>Catalogo persone</title>
</head>
<body>
<p>
Cognome: Sabatucci<br/>
Nome: Luca<br/>
</p>
<p>
Cognome: Rossi<br/>
Nome: Mario<br/>
</p>
</body>
</html>
Creazione di attributi
Modelli XSLT di default
<xsl:template match = "/ | *">
<xsl:apply-templates/>
</xsl:template>
Identifica il nodo radice del doc e tutti i nodi degli elementi.
Applica i modelli ai loro nodi child
<xsl:template match = “text() | @*">
<xsl:value-of select =“.”/>
</xsl:template>
Identifica i nodi di testo e i nodi degli attributi (@) e genera
l’output dei loro valori
<xsl:template match = “processing-instruction() |
comment()“/>
Identifica i nodi di istruzione di elaborazione e i nodi dei
commenti ma non svolge alcuna azione su di essi
Sorgente XML
<?xml version="1.0"?>
<!-- Fig. 12.4 : games.xml -->
<!-- Sports Database
-->
<sports>
<game title="cricket">
<id>243</id>
<para>
More popular among commonwealth nations.
</para>
</game>
<game title="baseball">
<id>431</id>
<para>
More popular in America.
</para>
</game>
<game title="soccer">
<id>123</id>
<para>
Most popular sport in the world.
</para>
</game>
</sports>
La trasformazione XSL
<?xml version = "1.0"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/
1999/XSL/Transform">
<xsl:template match = "/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match = "sports">
<sports>
<xsl:apply-templates/>
</sports>
</xsl:template>
<xsl:template match = "game">
<xsl:element name = "{@title}">
<xsl:attribute name = "id">
<xsl:value-of select = "id"/>
</xsl:attribute>
<comment>
<xsl:value-of select = "para"/>
</comment>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Il risultato della trasformazione
<?xml version="1.0" encoding="UTF-8"?>
<sports>
<cricket id="243">
<comment>
More popular among commonwealth nations.
</comment>
</cricket>
<baseball id="431">
<comment>
More popular in America.
</comment>
</baseball>
<soccer id="123">
<comment>
Most popular sport in the world.
</comment>
</soccer>
</sports>
Iterazioni e
ordinamento
Iterazioni e ordinamento
E’ possibile elaborare in modo iterativo I nodi
selezionati con un’espressione XPath.
Sui nodi si può anche operare un ordinamento
File dati XML
<?xml version="1.0"?>
<?xml:stylesheet type = "text/xsl" href = "usage.xsl"?>
<book isbn="999-99999-9-X">
<title>Deitel's XML Primer</title>
<author>
<firstName>Paul</firstName>
<lastName>Deitel</lastName>
</author>
<chapters>
<preface num="1" pages="2">Welcome</preface>
<chapter num="1" pages="4">Easy XML</chapter>
<chapter num="2" pages="2">XML Elements?</chapter>
<appendix num="1" pages="9">Entities</appendix>
</chapters>
<media type="CD"/>
</book>
La trasformazione XSLT - 1
<?xml version = "1.0"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match = "book">
<head>
<title>ISBN <xsl:value-of select = "@isbn"/> <xsl:value-of select = "title"/></title>
</head>
Continua
La trasformazione XSLT - 2
<body bgcolor = "white">
<h1><xsl:value-of select = "title"/></h1>
<h2>by <xsl:value-of select = "author/lastName"/>,
<xsl:value-of select = "author/firstName"/></h2>
<table border = "1">
<xsl:for-each select = "chapters/preface">
<xsl:sort select = "@num" order = "ascending"/>
<tr>
<td align = "right">
Preface <xsl:value-of select = "@num"/>
</td>
<td>
<xsl:value-of select = "."/> (
<xsl:value-of select = "@pages"/> pages )
</td>
</tr>
</xsl:for-each>
La trasformazione XSLT - 3
<xsl:for-each select = "chapters/chapter">
<xsl:sort select = "@num" order = "ascending"/>
<tr>
<td align = "right">
Chapter <xsl:value-of select = "@num"/>
</td>
<td>
<xsl:value-of select = "."/> (
<xsl:value-of select = "@pages"/> pages )
</td>
</tr>
</xsl:for-each>
La trasformazione XSLT - 4
<xsl:for-each select = "chapters/appendix">
<xsl:sort select = "@num" order = "ascending"/>
<tr>
<td align = "right">
Appendix <xsl:value-of select = "@num"/>
</td>
<td>
<xsl:value-of select = "."/> (
<xsl:value-of select = "@pages"/> pages )
</td>
</tr>
</xsl:for-each>
</table>
</body>
</xsl:template>
</xsl:stylesheet>
Il risultato della trasformazione
Il risultato della trasformazione
<html>
<head>
<META http-equiv="Content-Type"
content="text/html; charset=UTF-16">
<title>ISBN 999-99999-9-X - Deitel's XML
Primer</title>
</head>
<body bgcolor="white">
<h1>Deitel's XML Primer</h1>
<h2>by Deitel, Paul</h2>
<table border="1">
<tr>
<td align="right"> Preface 1</td>
<td>Welcome (2 pages )</td>
</tr>
<tr>
<td align="right">Chapter 1</td>
<td>Easy XML (4 pages )</td>
</tr>
Il risultato della trasformazione
<tr>
<td align="right">Chapter 2</td>
<td>XML Elements? (2 pages )</td>
</tr>
<tr>
<td align="right">Appendix 1</td>
<td>Entities (9 pages )</td>
</tr>
</table>
</body>
</html>
Istruzioni Condizionali
Il file dati XML
<?xml version="1.0"?>
<!-- Fig. 5.9 : planner.xml -->
<!-- Day Planner XML document -->
<planner>
<year value="2000">
<date month="7" day="15">
<note time="1430">Doctor's appointment</note>
<note time="1620">Physics class at BH291C</note>
</date>
<date month="7" day="4">
<note>Independence Day</note>
</date>
<date month="7" day="20">
<note time="0900">General Meeting in room 32-A</note>
</date>
Il file dati XML
<date month="7" day="20">
<note time="1900">Party at Joe's</note>
</date>
<date month="7" day="20">
<note time="1300">Financial Meeting in room 14-C</note>
</date>
</year>
</planner>
La trasformazione XSL
<?xml version = "1.0"?>
<!-- Fig. 12.11 : conditional.xsl
-->
<!-- xsl:choose, xsl:when, and xsl:otherwise -->
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
Appointments
<br/>
<xsl:apply-templates select = "planner/year"/>
</body>
</html>
</xsl:template>
<xsl:template match = "year">
<strong>Year:</strong>
<xsl:value-of select = "@value"/>
<br/>
<xsl:for-each select = "date/note">
<xsl:sort select = "../@day" order = "ascending"
data-type = "number"/>
<strong>
Day:
<xsl:value-of select = "../@day"/>/
<xsl:value-of select = "../@month"/>
</strong>
<br/>
<xsl:choose>
<xsl:when test =
"@time > '0500' and @time < '1200'">
Morning (<xsl:value-of select = "@time"/>):<xsl:when>
<xsl:when test =
"@time > '1200' and @time < '1700'">
Afternoon (<xsl:value-of select = "@time"/>):</xsl:when>
<xsl:when test =
"@time > '1200' and @time < '1700'">
Evening (<xsl:value-of select = "@time"/>):<xsl:when>
<xsl:when test =
"@time > '1200' and @time < '1700'">
Night (<xsl:value-of select = "@time"/>):<xsl:when>
<xsl:otherwise>
Entire day:
</xsl:otherwise>
</xsl:choose>
L’elemento choose si usa per
scegliere tra varie opzioni (tipo
switch del Java)
<xsl:value-of select = "."/>
<xsl:if test = ". = ''">
n/a
</xsl:if>
<br/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
L’elemento choose si usa per
specificare una sola condizione
Il risultato
Il risultato
<html>
<body>
Appointments<br>
<strong>Year:</strong>2000<br>
<strong>Day: 4/7</strong><br>
Entire day: Independence Day<br>
<strong>Day: 15/7</strong><br>
Afternoon (1430):Doctor's appointment<br>
<strong>Day: 15/7</strong><br>
Afternoon (1620):Physics class at BH291C<br>
Il risultato
<strong>Day: 20/7</strong><br>
Morning (0900):General Meeting in room 32-A<br>
<strong>Day: 20/7</strong><br>
Entire day:Party at Joe's<br>
<strong>Day: 20/7</strong><br>
Afternoon (1300):Financial Meeting in room 14-C<br>
</body>
</html>
Copiare i nodi
Copiare i nodi
XSLT permette di copiare i nodi dal file dati
XML di origine in quello creato con la
trasformazione
Ciò si fa con l’elemento copy che copia il nodo
di contesto
Il file dati XML
<?xml version="1.0"?>
<?xml:stylesheet type = "text/xsl" href = "copyIntro.xsl"?>
<myMessage>
<message>Welcome to XSLT!</message>
</myMessage>
XSLT
<?xml version = "1.0"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "myMessage">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match = "message">
<xsl:copy>
How about 'Hi World' for a change!
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Il risultato
<?xml version="1.0" encoding="UTF-8"?>
<myMessage>
<message>
How about 'Hi World' for a change!
</message>
</myMessage>
Esercizi
Esercizio 1
Scrivere un XSLT che trasformi il documento
della figura 12.28 in quello della figura 12.29
seguenti
Esercizio 2
Fare il viceversa (trasformare il doc di fig. 12.29
in quello di fig. 12.28)
Esercizio 3
Trasformare in HTML i due documenti
precedenti
Esercizio 4
Trasformare il file planner XML nella struttura
mostrata in figura 12.30
Il file dati PLANNER.XML
<?xml version="1.0"?>
<!-- Fig. 5.9 : planner.xml -->
<!-- Day Planner XML document -->
<planner>
<year value="2000">
<date month="7" day="15">
<note time="1430">Doctor's appointment</note>
<note time="1620">Physics class at BH291C</note>
</date>
<date month="7" day="4">
<note>Independence Day</note>
</date>
<date month="7" day="20">
<note time="0900">General Meeting in room 32-A</note>
</date>
Il file dati PLANNER.XML
<date month="7" day="20">
<note time="1900">Party at Joe's</note>
</date>
<date month="7" day="20">
<note time="1300">Financial Meeting in room 14-C</note>
</date>
</year>
</planner>
Figura 12.30