Indice

Logo Ufficio Italiano W3C

Logo CNR

Logo ISTI

 

 

 

 

 

  Valid XHTML 1.1! Valid CSS!

XSL

Massimo Martinelli
massimo AT w3c.it, massimo.martinelli AT isti.cnr.it

Ufficio Italiano W3C, CNR-ISTI

Area della Ricerca CNR

via Moruzzi, 1

56124 Pisa


logo Rete Telematica Regione Toscana logo Regione Toscana Corso AQUARIUS sulle Tecnologie Web

Firenze 16 Novembre 2010 - Pisa, 23 Novembre 2010

eXtensible Stylesheet Language (XSL)

3 parti

W3C Recommendations

A cosa serve XSLT

Consente di trasformare documenti XML in un altro formato:

Applicazioni

Premessa: Alberi

albero

Nodi dell'albero:

Il processo di trasformazione

processo di trasformazione

Trasformazioni

Lato client

Lato server

Programma

Due esempi

Funzionamento

Regole XSL-T

Template (sagoma)


<xsl:template match="modello">
... trasformazione ...
</xsl:template>

se sagoma uguale modello allora esecuzione della trasformazione

confronto tra sagoma e modello

Esempio di template

    <xsl:template match="nodo">
	 testo <tag> <xsl:value-of select="." /> </tag>
    </xsl:template>

Se un nodo del documento XML combacia con quello della regola dell'esempio viene prodotto come risultato

testo  <tag>  valore (contenuto) dell'elemento corrente </tag>

Dato il seguente frammento XML

<nominativo>Mario Rossi</nominativo>

e il il seguente frammento XSLT

<xsl:template match="nominativo">
       Nominativo: <strong><xsl:value-of select="."/></strong>
</xsl:template>

Risultato trasformazione:

Nominativo:  <strong>Mario Rossi</strong>

i nodi?

Abbiamo visto che una regola di template specifica un nodo come sagoma

ma come si specificano i nodi ? ...

XPath

Contesto

Passi di un percorso di localizzazione

Esempio di trasformazione di XML in HTML

Documento XML

<?xml version="1.0" encoding="UTF-8" ?>
<saluto>
	Benvenuto nel mondo di XSL-T
</saluto>

Documento XSL-T

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

<xsl:template match="/">
   <html>
     <head><title>Saluto</title></head>

     <body>
          <xsl:apply-templates select="saluto"/>
     </body>
   </html>
</xsl:template>

<xsl:template match="saluto">
     <xsl:value-of select="."/>
</xsl:template>

</xsl:stylesheet>

Risultato della trasformazione

Associare lo stile aggiungendo nel file xml alla 2a riga

<?xml-stylesheet href="esempio3_documento.xsl" title="stile" type="text/xsl"?>

e aprire il file per esempio con Firefox e osservare con firebug oppure con Opera

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  <-- aggiunta dal processore
<title>Saluto</title>
</head>
<body>
   Benvenuto nel mondo di XSL-T
</body>

</html>

Elementi di XSL-T

Nel successivo esempio vedremo questo template

Elementi di XSL-T

Esempio di trasformazione di XML in HTML

Documento XML

<?xml version="1.0" encoding="UTF-8" ?>
<documento>
	<autore>Mario Rossi</autore>
</documento>

 

Risultato della trasformazione

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Autore</title>
</head>
<body>Mario Rossi</body>

</html>

Documento XSL-T

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

<xsl:template match="/">
   <html>
     <head><title>Autore</title></head>
     <body>
          <xsl:apply-templates select="documento/autore"/>
     </body>
   </html>
</xsl:template>

<xsl:template match="autore">
     <xsl:value-of select="."/>
</xsl:template>

</xsl:stylesheet>

Un altro esempio

Documento XML

<?xml version="1.0" encoding="utf-8" ?>
<documento>
	<autore>Mario Rossi</autore>
</documento>

Documento XSLT

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

	<xsl:template match="autore">
		<div>Autore: <strong> <xsl:apply-templates /> </strong></div>
	</xsl:template>

</xsl:stylesheet>

Applica i template relativi agli elementi figli (ove ve ne siano)
...e non solo...

Il risultato della trasformazione

./esempiCorso2010/esempio3_risultato.xml

<div>
Autore:
<strong>Mario Rossi</strong>

</div>

Attenzione: non funziona come ci aspetteremmo perché esistono delle regole predefinite...

 

Esempio di template

<xsl:template match="nodo">
	 testo <tag> <xsl:apply-templates /> </tag>	
</xsl:template>
 testo  <tag>
   valore dell'elemento corrente                          <--regola di default
   applicazione delle altre regole di template 
</tag>

Regole XSLT precostituite, per difetto (default)


1.   <xsl:template match="/ | *">                       Applica le regole per qualsiasi elemento
         <xsl:apply-templates/>
      </xsl:template>

2.   <xsl:template match="text()">                      per qualsiasi testo
	  <xsl:value-of select="."/>
     </xsl:template>

3.  <xsl:template match="@*">                           La regola per gli attributi è "ingannevole"
	<xsl:value-of select="."/>                       Se non specifichiamo il template per gli attributi
    </xsl:template>                                     non vengono prodotti in output i valori

4.   <xsl:template match="comment()"/>                  Non applicare le regole per i  commenti

5.   <xsl:template match="processing-instruction()"/>   Ne per le istruzioni di processo

Esempio minimale #1

Dato il seguente file XML ...

<?xml version="1.0"?>
<biblioteca>
   <libro codice="R415">
	<titolo>Destinazione cervello</titolo>
	<autore>
		<cognome>Asimov</cognome>
		<nome>Isaac</nome>
	</autore>
	<editore>Mondadori</editore>
	<parola_chiave>romanzo</parola_chiave>
	<parola_chiave>fantascienza</parola_chiave>
   </libro>
      <libro codice="N516">
	<titolo>Sostiene Pereira</titolo>
	<autore>
		<cognome>Tabucchi</cognome>
		<nome>Antonio</nome>
	</autore>
	<editore>Feltrinelli</editore>
	<parola_chiave>romanzo</parola_chiave>
	<parola_chiave>narrativa</parola_chiave>
   </libro>
</biblioteca>

Esempio minimale #2

... e il seguente stylesheet minimale


<?xml version="1.0" encoding='UTF-8'?>

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

Esempio minimale #3

il risultato della trasformazione:

<?xml version="1.0" encoding="UTF-8"?>   <--Prologo XML


   
	Destinazione cervello
	
		Asimov
		Isaac
	
	Mondadori                <-- contenuto degli elementi senza i relativi tag
	romanzo
	fantascienza
   
      
	Sostiene Pereira
	
		Tabucchi
		Antonio
	
	Feltrinelli              <-- Attenzione agli spazi prodotti!!!

	romanzo                  Il secondo template di default ha 
	narrativa                prodotto in output anche gli spazi

Sostituzione delle regole precostituite

<xsl:template match="nodo">
</xsl:template>

Non applica alcuna trasformazione per il nodo specificato

 

<xsl:template match="*|text()" />

Non applica alcuna per gli elementi e per i testi (a meno di regole più specifiche)

Tipo di Output

apply-templates

<xsl:apply-templates/>

 

<xsl:apply-templates select="nodo" />

Output XHTML

<?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"
    doctype-public="-//W3C//DTD XHTML 1.1//EN"
    doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>

<xsl:template match="/">
   <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
       <title>esempio di output XHTML</title>
     </head>

     <body>
        <xsl:apply-templates />
     </body>
     </html>
</xsl:template>
  ...
</xsl:stylesheet>

Esercizio

Dato il seguente documento XML:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="brani.xsl" title="stile" type="text/xsl"?>
<brani>
    <brano id="5">
	<titolo>Asturias</titolo>
	<autore>Andres Segovia</autore>
	<incisione>Deutsche Grammophon</incisione>
    </brano>
</brani>

Trasformare in XHTML 1 (strict) in modo da produrre questo risultato:

                                Titolo brano: Asturias
                                Identificatore: 5
                                Incisione: Deutsche Grammophon

Risoluzione dei Conflitti - Precedenza tra template

La priorità di default è determinata come segue:

Esempi

Elementi di controllo:

condizioni

xsl:if (valori booleani) - Elaborazione condizionale ("if" senza "else")

<xsl:if test="$condizione">
    questo messaggio apparirà solo se $condizione è true
</xsl:if>

Dividiamo gli autori con una virgola:

<xsl:template match="autore">
   <xsl:value-of select="./cognome" />
   <xsl:text>  </xsl:text>

   <xsl:value-of select="./nome" />
   <xsl:apply-templates />
   <xsl:if test="not(position()=last())">, </xsl:if>
</xsl:template>                          ^

Dichiarazione di variabili - xsl:variable

<xsl:variable name="var" expr="subelement[position() mod 3]"/>

* Notare la dichiarazione di una variabile il cui valore è una espressione matematica

apply-template multipli

<xsl:template match="film">
  <h1> elenco dvd</h1>
  <table>
    <xsl:apply-templates select="dvd"/>
  </table>
  <h1> elenco videocassette</h1>
  <table>
  	<xsl:apply-templates select="cassetta"/>
  </table>
</xsl:template>

xsl:choose - alternative

Supponiamo di dover gestire la prenotazione di lezioni che possono essere di gruppo o individuali

<xsl:template match="lezione">
    <h3><xsl:value-of select="titoloLezione"/></h3>
    <h4>Aula: <xsl:value-of select="../../@name"/></h4>

    <h4>Prenotata da : <xsl:value-of select='prenotataDa'/></h4>
    <h4>Allievi:</h4>
    <xsl:for-each select='allievi'>
      <xsl:choose>

        <xsl:when test="gruppo">   <-- Esiste un elemento gruppo figlio dell'elemento corrente ?
          &#160;&#160;Gruppo: <em><xsl:value-of select="gruppo"/></em><br />

        </xsl:when>
        <xsl:otherwise>
          &#160;&#160;<xsl:value-of select="individuo"/><br />
        </xsl:otherwise>

      </xsl:choose>
    </xsl:for-each>
    <p> dalle ore <xsl:value-of select="oriario/da"/> 
	     alle ore <xsl:value-of select="orario/alle"/></p>

     . . .
</xsl:template>                    &#160; == &nbsp;

xsl:choose #2

<xsl:template match="elemento">

     <xsl:variable name="var" expr="sottoelemento[position() mod 3]"/>
      <xsl:choose>
        <xsl:when test='$var=1'>
          ... fai qualcosa...
        </xsl:when>
      <xsl:when test='$var=2'>

	     ... fai un'altra cosa ...
        </xsl:when>
        <xsl:otherwise>
          ... fai qualcosaltro ...
        </xsl:otherwise>
      </xsl:choose>
  <xsl:apply-templates/>

</xsl:template>

xsl:sort

Modificare l'ordine dei libri per autore

<xsl:template match="biblioteca">
	<xsl:apply-templates select="libro[code >= 'M']" >
		<xsl:sort select="libro/autore/cognome" />			  Ordina per cognome
		<xsl:sort select="libro//nome" />					poi per nome
	</xsl:apply-templates>
</xsl:template>

Supponendo di voler modificare l'ordine per prezzo (numerico)

<xsl:sort select="libro/prezzo"
		order="descending"            Specifica l'ordine discendente (per difetto = ascending)
		data-type="number" />			Specifica il tipo di dato (per difetto = text)

xsl:element

<xsl:element name="nome_elemento">

Crea un elemento <nome_elemento> e lo restituisce in uscita

<xsl:element name="cognome">
	 <xsl:value-of select=".">

</xsl:element>

Crea un elemento <cognome> contenente il valore dell'elemento corrente

xsl:attribute

<xsl:attribute name="nome_attributo">

Crea un attributo nome_attributo su <xsl:element> corrente.

Il contenuto di <xsl:attribute> diventa il valore dell'attributo creato

<indirizzo_sito_web>http://www.cnr.it</indirizzo_sito_web>


<xsl:element name="a">
	<xsl:attribute name="href">
		<xsl:value-of select="indirizzo_sito_web">
	</xsl:attribute>
   il sito web del CNR

</xsl:element>
<a href="http://www.cnr.it">il sito web del CNR</a>

Invocazione di template ("procedure")

XSL-T permette di invocare una regola template con passaggio di parametri

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

<xsl:param name="nome" />		// parametro con visibilità globale

<xsl:template name="calcoloArea">
	<xsl:param name="larghezza" />
	<xsl:param name="altezza" />	
	<xsl:value-of select="$larghezza * $altezza" />
</xsl:template>
<xsl:call-template name="calcolaArea">		// invoca il template
	<xsl:with-param  name="larghezza" select="10" />	// passaggio di parametro
	<xsl:with-param  name="altezza" select="20" />	// passaggio di parametro
</xsl:call-template>

</xsl:stylesheet>

I template si possono invocare ricorsivamente (call template all'interno dello stesso template che chiama)
Un ottimo esempio è il template Somma riportato nel capitolo 7 sezione 2 del libro "XSL-T" O'Reilly
http://oreilly.com/catalog/orxmlapp/chapter/ch07.html

document

Un foglio di stile può elaborare più di un documento XML caricando altri documenti con la funzione document()

prodotti.xml

<?xml version="1.0"?>
<prodotti>
    <prodotto>
         <nome>Monitor<nome>
         <prezzo valuta="eu">900</prezzo>
         <descrizione>Display LCD ... </descrizione>
    </prodotto>
    ...
</prodotti>

valute.xml

<?xml version="1.0"?>
<valute>
    <valuta>
         <codice>eu<codice>
         <nome>Euro<nome>
    </valuta>
    ...
</valute>
...
<xsl:variable
   nome=valute
   select="document(valute.xml)/valute" />
...
<xsl:template match="prodotto">
     <xsl:variable name="valuta" select="prezzo/@valuta" />
     <xsl:value-of select="prezzo" />
      <xsl:value-of select="$valute/valuta[codice="$valuta"]/nome" />
     <xsl:value-of select="descrizione" />
</xsl:template>

Preparazione all'esercizio (Trasformazione lato server o da linea di comando)

Esempi

Analizziamo gli esempi iniziali
trasformazione di un stesso documento XML in SVG, HTML e PDF

Risorse su XSLT

Ringraziamenti

Grazie per l' attenzione

Domande?


Se non è sul Web non esiste ...

... troverete le slide all'indirizzo http://www.w3c.it/projects/aquarius/presentazioni/moduloD/xml/indexConsegnare.html e http://www1.isti.cnr.it/~Martinelli/XML/doc/TecnologieWeb/xsl/index.html