[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [translators] [docinfo] [indice analitico] [volume] [parte]
XSLT è un linguaggio realizzato in forma di file XML, con il quale si definisce una trasformazione di un file XML in un altro file. Generalmente, il file di destinazione è un altro file XML, anche se può comunque essere qualcosa di diverso. La sigla sta precisamente per XSL transformations (ovvero Extensible stylesheet language transformations), a indicare che il linguaggio è scritto in quello che viene chiamato «foglio di stile XSL» e serve a trasformare i dati originali in qualcosa di conveniente ai propri scopi. In altri termini, si tratta di un linguaggio che consente di estrarre le informazioni contenute in un file XML, per generare con queste ciò che serve.
|
Naturalmente, l'elaborazione di un file XML secondo il linguaggio XSLT richiede un programma apposito. In questo capitolo viene mostrato a l'uso di Xalan (sezione 337.6).
La trattazione che qui viene fatta a proposito dei fogli di stile XSLT è limitata alle funzionalità principali. Per un approfondimento si può consultare la documentazione elencata nella bibliografia alla fine del capitolo.
Un documento XML, ai fini della sua elaborazione, viene visto come una struttura ad albero, dove ogni componente rappresenta un nodo di questo. Si osservi l'esempio seguente, che rappresenta un file XML molto semplice:
|
Si potrebbe rappresentare schematicamente l'albero di questo documento come si vede nella figura successiva:
|
Nello schema mostrato si deve osservare che elementi, attributi e testo contenuto negli elementi, costituiscono nodi separati.
Per identificare un nodo dell'albero, si usa una notazione che assomiglia ai percorsi dei file system Unix. A titolo di esempio vengono mostrati tutti gli elementi e gli attributi XML degli schemi già apparsi, secondo la sequenza originale, con percorsi assoluti:
|
Naturalmente esistono anche percorsi relativi, quando manca la barra obliqua iniziale che rappresenta la radice: questi fanno riferimento al nodo corrente nell'ambito del contesto a cui ci si riferisce.
La sintassi con cui si possono definire questi percorsi è stabilita dal linguaggio XPath, ovvero XML path language. Si tratta di un sistema abbastanza complesso che non viene mostrato qui nel dettaglio. Per quanto riguarda il linguaggio XSLT i percorsi vengono usati per definire un modello di confronto con i nodi di un documento XML; nell'ambito di questi modelli di confronto si utilizzano delle notazioni particolari rispetto alla convenzione generale costituita da XPath. La tabella 337.5 riporta alcuni esempi di questi modelli.
|
Un foglio di stile XSLT è un documento XML con una struttura particolare, abbinato al dominio applicativo <http://www.w3.org/1999/XSL/Transform> (sezione 336.5). Normalmente, il prefisso associato a questo dominio applicativo è xsl, pertanto, l'elemento principale è xsl:stylesheet, oppure xsl:transform, indifferentemente:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" [altri_attributi]> [contenuto] </xsl:stylesheet> |
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" [altri_attributi]> [contenuto] </xsl:transform> |
Anche senza definire esplicitamente alcun tipo di trasformazione, si ottiene ugualmente un risultato elaborando un file XML, attraverso delle regole di trasformazione predefinite, con le quali, in buona sostanza, si ottiene il testo del file XML, senza i marcatori che delimitano gli elementi. Per esempio, si può prendere il file XML già presentato all'inizio del capitolo, associandogli il foglio di stile seguente:
|
Supponendo che il file XML si chiami prova.xml
e che il foglio di stile sia prova.xsl
, si potrebbe usare Xalan nel modo seguente:
$
xalan -IN prova.xml -XSL prova.xsl -OUT prova.txt
[Invio]
Ecco cosa si ottiene nel file prova.txt
:
|
La definizione di un criterio di trasformazione dei nodi del documento XML di origine in quello che si vuole ottenere, avviene principalmente per mezzo di modelli di confronto, attraverso un elemento del foglio di stile denominato xsl:template. La traduzione del termine template, ovvero «mascherina», rende bene l'idea del concetto: gli elementi xsl:template del foglio di stile definiscono un modello di confronto con cui selezionano alcuni nodi del documento XML di origine; su questi nodi applicano delle trasformazioni.
<xsl:template match="modello_di_confronto" [altri_attributi]> trasformazione </xsl:template> |
Il modello di confronto viene definito secondo le regole che in parte sono state descritte nella tabella 337.5; per esempio, il blocco seguente individua il nodo radice:
|
Per comprendere meglio cosa accade, si prenda il solito esempio di file XML già considerato in precedenza e si applichi il foglio di stile seguente:
|
Come si vede, è stato inserito un solo elemento xml:template che seleziona l'elemento contenuto, che si trova all'interno di relazione (che a sua volta è l'elemento principale del documento XML). Quando si individua questo elemento, viene inserito il testo «ciao ciao». Valgono le stesse convenzioni dei nomi dei file già viste in precedenza:
$
xalan -IN prova.xml -XSL prova.xsl -OUT prova.txt
[Invio]
Ecco cosa si ottiene nel file prova.txt
:
|
In pratica, le regole di trasformazione predefinite hanno inserito il contenuto degli elementi titolo e data. Quindi, l'elemento contenuto, con tutto quello che esiste al suo interno, è stato sostituito con la stringa «ciao ciao».
Per fare in modo che vengano presi in considerazione anche gli elementi contenuti all'interno di ciò che viene individuato, si utilizza l'elemento xsl:apply-templates, che di solito è vuoto:
<xsl:template match="modello_di_confronto" [altri_attributi]> ... <xsl:apply-templates [select="modello_di_selezione"] [altri_attributi]> ... </xsl:apply-templates> ... </xsl:template> |
Per esempio, se il foglio di stile di prova viene modificato nel modo seguente:
|
La trasformazione genera questo file:
|
In pratica, si consente alle regole di trasformazione predefinite (dal momento che non ce ne sono altre nell'esempio) di occuparsi degli elementi contenuti all'interno dell'elemento contenuto, cosa che produce semplicemente l'estrazione del testo che questi circoscrivono. Tutto questo avviene perché «l'istruzione» apply-templates serve proprio a richiamare gli altri modelli di confronto (e trasformazione) per quanto è contenuto in ciò che è stato individuato.
Dal momento che nell'esempio non ci sono altri modelli di confronto e trasformazione, è evidente che si tratta soltanto di quelli predefiniti. |
L'elemento xsl:apply-templates può avere un attributo molto importante, select, che consente di specificare su cosa continuare il confronto con altri modelli; in pratica consente di limitare, o controllare, la ricorsione. Si osservi la variante seguente del foglio di stile:
|
Per prima cosa è bene osservare che il modello indicato con l'attributo select rappresenta un percorso relativo, che secondo il contesto è riferito esattamente a /relazione/contenuto/paragrafo
. In base a questa selezione, si vuole che nell'ambito del contenuto dell'elemento (o degli elementi) /relazione/contenuto
, la ricorsione successiva prenda in considerazione soltanto gli elementi paragrafo. Ecco cosa si ottiene; come si vede, il testo dell'elemento firma è stato ignorato:
|
Naturalmente, è possibile utilizzare xsl:apply-templates più volte all'interno dello stesso modello di confronto e trasformazione, anche così:
|
Ecco il risultato che si può ottenere:
|
I modelli di confronto e trasformazione possono basarsi su riferimenti relativi ai nodi, se non ha importanza la collocazione esatta di questi nell'albero del documento XML di origine. Si osservi l'esempio seguente:
|
In questo caso, si evidenziano gli elementi paragrafo, attorno ai quali si vuole appaiano gli apici doppi; tutto il resto viene gestito in modo predefinito:
|
Come accennato, l'elemento xsl:apply-templates del foglio di stile XSLT, normalmente è vuoto. Quando contiene qualcosa, ciò serve per elaborare il risultato della scansione che lo riguarda. In pratica, xsl:apply-templates serve a richiamare i modelli di confronto e trasformazione successivi, in modo da inserire il risultato di queste elaborazioni nel punto in cui si trova, ma se questo elemento non è vuoto, le «istruzioni» che contiene servono a interferire con le elaborazioni successive, per esempio per riordinare i dati ottenuti. Questo tipo di utilizzo di xsl:apply-templates non viene descritto.
Negli esempi delle sezioni precedenti, in varie occasioni è stato inserito del testo aggiuntivo nella trasformazione del documento XML di origine. In questo modo è possibile anche aggiungere marcatori e altre componenti, in base agli scopi che ci si prefigge con la trasformazione.
Quando un elemento contiene solo spazi bianchi (spazi veri e propri, tabulazioni orizzontali e interruzioni di riga), il nodo relativo può essere eliminato dalla struttura. In generale, salvo che sia specificato diversamente, nel documento XML di origine vengono preservati tutti gli spazi, mentre nel foglio di stile sono preservati solo quelli contenuti negli elementi xsl:text.
Esistono diverse modalità di funzionamento a cui si adegua la trasformazione del documento XML, in base al tipo di file che si vuole ottenere. Questa modalità di funzionamento si seleziona con l'elemento xsl:output:
<xsl:output method="metodo" version="versione" encoding="codifica" omit-xml-declaration="yes"|"no" doctype-public="dichiarazione_dtd_public" doctype-system="dichiarazione_dtd_system" [altri_attributi] /> |
Come si vede dal modello sintattico, si tratta di un elemento del foglio di stile che non ha lo scopo di contenere qualcosa e tutto è indicato attraverso attributi.
L'attributo più importante è method, al quale si associano normalmente le parole chiave xml, html e text, per indicare rispettivamente che si vuole ottenere un risultato in formato XML, HTML o un file di testo senza una conformazione particolare conosciuta. In generale, se non si specifica il formato del file che si va a generare, si intende XML, cosa che dovrebbe spiegare il motivo per cui negli esempi mostrati in precedenza appare la dichiarazione XML anche se il file ottenuto è semplicemente un testo puro e semplice.
Come si può intuire, a seconda del tipo di «metodo» prescelto, gli altri attributi possono acquisire o perdere significato.
|
|
Generalmente è sufficiente aggiungere del testo estraneo all'interno del foglio di stile XSLT, nell'ambito degli elementi xsl:template, per fare in modo che questo venga inserito nel risultato finale. Per avere un controllo maggiore si può usare l'elemento xsl:text, che tra le altre cose permette di inserire blocchi di spazi quando diversamente verrebbero eliminati:
<xsl:text [disable-output-escaping="yes"|"no"]> testo </xsl:text> |
L'attributo disable-output-escaping permette, se si assegna il valore yes, di disabilitare la sostituzione di alcuni caratteri in entità generali standard (questo vale solo per le trasformazioni che prevedono nella destinazione un formato XML o HTML, perché nel caso di trasformazioni in formato testo, questa sostituzione non viene mai eseguita). Come si può intendere, la funzionalità è disabilitata in modo predefinito, pertanto, normalmente si ottiene la sostituzione di questi caratteri.
In alcune circostanze è necessario inserire del testo nel foglio di stile XSLT che non deve essere interpretato prima della trasformazione, lasciandolo in modo letterale. Per questo si usa normalmente una sezione marcata di tipo CDATA, come nell'esempio seguente, dove si vede l'intenzione di inserire uno stile CSS nel documento finale che è un file HTML:
|
Il testo contenuto in un nodo viene inserito nel documento finale attraverso l'elemento xsl:value-of del foglio di stile. Esiste anche un modello di confronto e trasformazione predefinito che esegue questa operazione per tutti i nodi di testo, pertanto, negli esempi di fogli di stile non si è ancora presentata la necessità di mostrarne l'uso:
<xsl:value-of select="modello_di_selezione" [disable-output-escaping="yes"|"no"] /> |
Come si vede dal modello sintattico, l'elemento xsl:value-of si usa vuoto e, per ottenere il «valore» di qualcosa, occorre specificarlo attraverso un modello di selezione, come avviene con l'elemento xsl:apply-templates.
Anche questo elemento prevede l'attributo disable-output-escaping come descritto a proposito di xsl:text.
L'elemento xsl:value-of si può usare per estrarre il testo contenuto in un elemento del documento di origine, oppure per fare altrettanto da un attributo; in generale, è più frequente l'uso di xsl:value-of per estrarre il testo di un attributo, come nell'esempio seguente:
|
In questo caso, quando si raggiunge un elemento denominato relazione, nel documento XML di origine, viene estratto il valore dell'attributo lang di questo e inserito in una frase, ignorando qualunque altra cosa che possa riguardare l'elemento in questione.
Quando il documento di destinazione è di tipo XML o HTML, è probabile che si vadano a descrivere dei marcatori che contengono la dichiarazione di attributi. Quando negli attributi si vuole inserire un valore estratto da un nodo del documento XML di origine, non si può usare l'elemento xsl:value-of; al suo posto si usano delle parentesi graffe, come nell'esempio seguente:
|
Questa volta, come si può vedere, si va a costruire un documento HTML, dove serve il valore dell'attributo lang dell'elemento relazione del file di partenza.
Quando il formato di destinazione della trasformazione è un file XML o HTML, è possibile creare alcune componenti tipiche di questi file con l'ausilio di elementi appositi nel foglio di stile XSLT.
Quando per qualche ragione è difficile inserire letteralmente il testo che rappresenta i marcatori di un elemento nel documento finale, si può usare nel foglio di stile XSLT l'elemento xsl:element:
<xsl:element name="nome_elemento" [altri_attributi]> contenuto </xsl:element> |
Per dichiarare un attributo si può usare l'elemento xsl:attribute:
<xsl:attribute name="nome_attributo" [altri_attributi]> contenuto </xsl:element> |
L'esempio seguente mostra l'uso di questi due elementi, per la costruzione della prima parte di un documento HTML, dove in particolare si vede anche l'uso di xsl:value-of:
|
Osservando l'esempio si intende che il documento XML di origine contiene l'elemento relazione all'inizio della gerarchia; inoltre al suo interno si trova l'elemento titolo che viene usato per completare l'intestazione del file HTML.
Quando il formato di destinazione è di tipo XML o HTML è possibile inserire dei commenti attraverso l'elemento xsl:comment nel foglio di stile XSLT:
<xsl:comment> contenuto </xsl:comment> |
In modo analogo, è possibile inserire istruzioni di elaborazione quando il formato di destinazione è di tipo XML, con l'elemento xsl:processing-instruction:
<xsl:processing-instruction name="nome_istruzione"> contenuto </xsl:processing-instruction> |
Si osservi l'esempio seguente:
|
In questo modo, all'inizio del documento di destinazione si ottiene il testo seguente:
|
Xalan (1) è un elaboratore XSLT disponibile sia in Java, sia in C++. Qui si fa riferimento all'uso di Xalan-C++, ovvero a un programma compilato in modo da avere un eseguibile che non richiede altre forme di interpretazione:
xalan -IN documento_xml_originale -XSL foglio_di_stile \ |
Il modello sintattico mostrato è più che sufficiente per usare bene Xalan; per le altre opzioni disponibili si può consultare la pagina di manuale xalan(1).
Durante l'elaborazione, Xalan emette alcune informazioni ed eventualmente delle segnalazioni di errore, che dovrebbero tornare utili per correggere il foglio di stile XSLT. Si osservi che quando si procede a una trasformazione che deve generare un documento XML o HTML, Xalan si sofferma anche su errori relativi al formato finale. Per esempio, l'estratto seguente, riferito proprio alla generazione di codice HTML genera un errore a causa della mancata chiusura dell'elemento HEAD nel file che si ottiene:
|
Supponendo che il file XML originale sia prova.xml
, che il foglio di stile XSLT sia contenuto nel file prova.xsl
e che si voglia generare il file prova.html
, si dovrebbe procedere con il comando seguente:
$
xalan -IN prova.xml -XSL prova.xsl -OUT prova.html
[Invio]
In questo caso, si ottiene l'errore già descritto:
========= Parsing prova.xsl ========== Fatal Error at (file prova.xsl, line 12, column 18): \ |
I riferimenti ai numeri di riga dell'esempio sono corretti, pertanto si può osservare che gli errori vengono segnalati in posizioni abbastanza lontane rispetto alla loro collocazione effettiva.
Nelle sezioni seguenti vengono mostrati diversi fogli di stile XSLT per ottenere altrettante trasformazioni a partire da un file XML già mostrato in precedenza. Qui viene riportato nuovamente, con qualche piccola modifica e con l'aggiunta della dichiarazione del DTD incorporata:
|
Si osservi che questo file, come si vede dalla dichiarazione iniziale, deve usare la codifica UTF-8; di conseguenza, le lettere accentate utilizzano più di un byte per essere rappresentate.
Per la trasformazione in un sorgente LaTeX si deve utilizzare un foglio di stile XSLT che elabora il risultato in modalità testo:
|
Si può osservare che non sono state stabilite delle regole di trasformazione per gli elementi data, paragrafo e firma, perché allo scopo risultano sufficienti le regole predefinite. Inoltre, le parentesi graffe sono usate fuori dal contesto in cui servono per ottenere il valore di qualcosa, pertanto hanno soltanto un significato letterale nell'ambito della trasformazione. Ecco cosa si ottiene:
|
Il file che si ottiene utilizza la codifica UTF-8, cosa che consente di evitare l'uso di comandi particolari per rappresentare le lettere accentate, pertanto si è reso necessario l'utilizzo di un «pacchetto» adatto allo scopo (\usepackage[utf8]{inputenc}). Tuttavia rimangono da risolvere altri problemi legati a caratteri che non possono essere inseriti letteralmente, come per esempio nel caso di %, che per LaTeX costituisce l'inizio di un commento. Per questo occorrerebbe inserire nel DTD la dichiarazione di una serie di entità generali, che poi devono essere usate nel sorgente XML.
Infine, si noti che, per semplicità, nella trasformazione viene ignorato completamente il linguaggio, ovvero l'attributo lang dell'elemento relazione.
Per la trasformazione in un sorgente HTML si deve utilizzare un foglio di stile XSLT che elabora il risultato in modalità HTML, avendo cura, possibilmente, di predisporre anche la dichiarazione del DTD:
|
Questa volta il foglio di stile XSLT è molto più articolato, anche perché incorpora la dichiarazione di alcuni stili CSS. Ecco il risultato che si ottiene; si osservi che il file viene generato usando la codifica ISO-8859-1:
|
Per la trasformazione in un sorgente XHTML si deve utilizzare un foglio di stile XSLT che elabora il risultato in modalità XML:
|
Il risultato che si ottiene manca di alcuni incolonnamenti che nelle altre situazioni venivano mantenuti. Per ovviare all'inconveniente, si può provare ad aggiungere l'attributo indent="yes" nell'elemento xsl:output:
|
Ecco il risultato, incolonnato, che si può ottenere:
|
Si ricorda che in questo caso la codifica del file generato è UTF-8, inoltre, si fa notare che nel foglio di stile XSLT appare un dominio applicativo predefinito, allo scopo di riportarlo nel file XHTML di destinazione.
W3C, XSL Transformations (XSLT)
W3C, XML Path Language (XPath)
Elliotte Rusty Harold, XML Bible
Elliotte Rusty Harold, XML Bible, second edition: XSL Transformations
<http://www.ibiblio.org/xml/books/bible2/chapters/ch17.html>
O'Reilly, xml.com
Cover Pages
Michele Sciabarrà, Tutorial XML/XSLT
Michele Sciabarrà, Linux e programmazione web, McGraw-Hill, 2001, ISBN 88-386-4177-3
In particolare il capitolo XML e XSLT.
Appunti di informatica libera 2006.07.01 --- Copyright © 2000-2006 Daniele Giacomini -- <daniele (ad) swlibero·org>
1) Xalan software libero con licenza speciale
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome introduzione_ai_fogli_di_stile_xslt.htm
[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [translators] [docinfo] [indice analitico]