Un foglio di stile XSLT visto da vicino
Abbiamo anche visto, ma lo vedremo meglio in seguito, la prima trasformazione di un documento XML nel browser Internet Explorer. Nella lezione odierna vedremo l´"anatomia" di un documento XSLT. Esso è composto da alcuni elementi base e da una struttura la quale deve necessariamente essere rispettata per la buona riuscita della trasformazione.
Fino ad ora abbiamo introdotto sia il termine "foglio di stile XSLT" che documento XSLT. La dicitura esatta è fogli di stile. Mi rendo conto che potrebbe essere fuorviante perchè potremmo confonderli con i fogli di stile a castata, o CSS. Quando si lavora con i CSS, questi definiscono lo stile oppure il layout di alcuni tag XHTML. Sappiamo benissimo che possiamo, con i CSS, definire il carattere (dimensioni e colore), stile dei bordi, colore di sfondo ecc...
Nel caso di XSLT, invece, un foglio di stile si comporta diversamente: crea un output da un documento XML che potrebbe, ma non sempre, contenere informazioni di formattazione. L´output può anche contenere solo una parte dei dati del documento XML; inoltre questi dati si possono ordinare e strutturare. Tutto questo non si può ottenere con i CSS.
Il prologo XML
Un prologo "tipico" contiene una istruzione di elaborazione che indica al parser o al processore la versione o il tipo di codifica del documento XML. Una istruzione tipica di elaborazione è la seguente:
Dobbiamo avere questa istruzione di elaborazione al primo rigo del documento. La codifica è un elemento facoltativo ma sarebbe opportuno utilizzarlo sempre in quanto, così facendo, siamo sicuri che i caratteri speciali siano trattati nella maniera adeguata.
L'elemento foglio di stile
Un documento XML ha sempre uno ed un solo elemento radice. Nel caso di un foglio di stile questo elemento è xsl:stylesheet. Un elemento stylesheet si presenta in questo modo:
L´elemento xsl:stylesheet è obbligatorio ed il suo valore deve essere una versione valida. Il secondo attributo non possiamo definirlo XSLT vero e proprio. È una dichiarazione di un namespace comune a tutti i documenti XML che fanno uso di namespace.
L'elemento transform
Ci sono fogli di stile che hanno un elemento radice chiamato xsl:transform. Questo elemento è uguale all´elemento xsl:stylesheet. Usare l´uno o l´altro è la stessa ed identica cosa.
Il contenuto di un foglio di stile
L´elemento xsl:stylesheet è un elemento vuoto. Di conseguenza possiamo aspettarci che non accada nulla quando un processore lo esegue. Potremmo pensare che qualsiasi documento XML al quale viene applicato un foglio di stile mandi in output un documento vuoto; ma questo non accade in quanto il comportamento di default di XSLT non prevede ciò quando non si applicano regole. Riprendiamo il file che abbiamo usato in precedenza, amici.xml. Nel file .xsl eliminiamo ogni tag di trasformazione in maniera tale che appaia come il codice riportato di seguito:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="ISO-8859-1" indent="yes" />
</xsl:stylesheet>
e vediamo cosa accade se richiamiamo il file amici.xml nel browser, come nell´esempio. Qualcosa è successo. Il valore dei due elementi amico e amico_2 sono stati stampati a video. Magari non come non volevamo ma, comunque, sono stati visualizzati.
Crearsi delle proprie regole
Dal file che abbiamo visto, richiamato nel browser, la regola contenuta all´interno del foglio di stile XSLT, non sembra sia molto utile. Ma non è così; essa è utile solo quando possiamo controllarne il comportamento. Crearsi delle regole è il primo passaggio per il controllo dell´output. Si possono creare delle regole con usando l´elemento xsl:template. Ma di questo parleremo in seguito.
Usare l'attributo match
Un modello, altrimenti detto template mette in corrispondenza l´elemento, o attributo, corrente che il processore trova nel documento XML con la corrispondente regola del modello stesso. Se la regola del modello corrisponde all´elemento corrente, quel modello viene eseguito ed applicato a quell´elemento. La regola che viene usata per far corrispondere elementi ed attributi viene definita usando l´attributo match del modello. Facciamo un piccolo esempio: un modello che corrisponde ad un elemento chiamato amici (per avere come riferimento il nostro file di esempio) in un documento XML, deve essere scritta nel seguente modo:
Se applicassimo questa regola ad un documento XML che contiene un elemento amici, tutte le volte che viene trovato questo elemento il testo "I miei amici"viene scritto nella pagina. Il codice che abbiamo scritto poco fa contiene un modello che corrisponde a qualunque elemento amici nel documento sorgente al quale è applicato il modello. L´output di questo file lo possiamo vedere nell'esempio.
Nonostante il risultato appena visto nel browser non contenga nulla di particolarmente eccezionale, è molto importante. La regola (il rigo di codice) corrispondente a qualsiasi elemento amici viene innescato solo una volta e viene applicata perchè incontra il modello corrispondente all´elemento amici. Quel modello viene eseguito e viene inserito il testo >I miei amici:<. Oltre questo, non accade altro. Se nessun modello trova corrispondenza, la regola del modello passa a processare gli elementi figli. Quando un modello trova un elemento corrispondente, deve dichiarare in maniera esplicita di continuare ad elaborare tutti gli elementi figli; in questo caso ciò non accade. Proviamo adesso un altro esempio. Modifichiamo il file amici.xml iniziale e facciamolo diventare in questo modo:
<?xml-stylesheet type="text/xsl" href="/amici4.xsl"?>
<amici>
<amico>Mario</amico>
<amico>Gianni</amico>
</amici>
La regola che vogliamo creare nel foglio di stile XSLT deve operare su qualsiasi elemento amico, per cui scriviamo:
<xsl:template match="amico">
I miei amici:<br />
</xsl:template>
</xsl:stylesheet>
Il risultato è facilmente intuibile e possiamo vederlo nel file di esempio. La differenza dal codice precedente è che in questo caso abbiamo creato un modello che corrisponde a qualsiasi elemento <amico>. La regola viene innescata 2 volte; una per ogni elemento <amico>. Il processore prima incontra la radice del documento.Siccome non è stata creata nessuna regola, passa alla successiva la quale istruisce nel seguente modo: Per ogni elemento figlio (2 nel nostro caso), copia il valore del testo. Se avessimo avuto, come nel file iniziale XML, anche attributi per gli elementi <amico>, sarebbero stati stampati? No! Perchè la regola dice di trovare una corrispondenza con gli elementi figli, e non con i figli dei figli (nel nostro caso gli attributi).
Vediamo adesso un esempio che mette assieme le due regole del foglio di stile ed osserviamo bene cosa sucdede. Acquisito il concetto appena esposto, dovremmo essere in grado di prevedere quello che otterremo, prima di visualizzare l´output della pagina. Il documento XML sorgente rimane quello del codice più su riportato, con le modifiche e senza gli attributi x gli elementi.
<xsl:template match="amici">I miei amici.</xsl:template>
<xsl:template match="amico">Il mio amico.</xsl:template>
</xsl:stylesheet>
Vogliamo vedere subito l´output del file di esempio oppure tiriamo ad indovinare quello che accadrà? Come avrete certamente visto, otteniamo lo stesso risultato che abbiamo avuto quando abbiamo scritto
nonostante abbiamo inserito 2 regole. Perchè? Perchè la regola incorporata ha incontrato prima l´elemento <amici> innescando, giustamente, la regola appropriata. Siccome l´elemento <amico> è figlio di <amici>, la regola non verrà mai applicata ai figli. Il modello definito per l´elemento <amico> non ha un comando che istruisce il processore di richiamare una regola che comprenda anche i suoi figli, per cui l´elaborazione si arresta subito dopo che ha trovato l´elemento <amici>.
| < Prec. | Succ. > |
|---|

