- I template XSLT -
 
COSA SERVE PER QUESTO TUTORIAL
Download | Chiedi sul FORUM | Glossario Un qualunque editor testuale e Internet Explorer, Opera o Firefox oppure un server che supporti ASP .Net o PHP
I template: xsl:template e xsl:apply-templates

XSL:TEMPLATE
Introduzione ai template

In questo articolo ci proponiamo di comprendere a fondo il funzionamento di ciò che sta alla base dei vari elaboratori XSLT: i template. Abbiamo visto nell'articolo di introduzione a XSLT l'elemento xsl:template e abbiamo detto che serve per indicare quale output l'elaboratore dovrà generare incontrando un nodo (parte del documento XML) che corrisponde all'espressione XPath dell'attributo match. Ad esempio:


<?xml version="1.0" encoding="iso-8859-1"?>
<clienti>
    <persona codicefiscale="MRARSS50A01A390K">
        <nome>Mario</nome>
        <cognome>Rossi</cognome>
        <altezza>1,80 m</altezza>
        <peso>75 Kg</peso>
        <professione>impiegato</professione>
    </persona>
    <persona codicefiscale="PLORSS50A01A390K">
        <nome>Paolo</nome>
        <cognome>Rossi</cognome>
        <altezza>1,75 m</altezza>
        <peso>80 Kg</peso>
        <professione>dirigente</professione>
    </persona>
    <persona codicefiscale="CRLRSS50A01A390K">
        <nome>Carlo</nome>
        <cognome>Rossi</cognome>
        <altezza>1,90 m</altezza>
        <peso>80 Kg</peso>
        <professione>meccanico</professione>
    </persona>
</clienti>

Se sottoposto alla seguente trasformazione XSL:


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="persona">
        <div>Ho appena incontrato una persona: <xsl:value-of select="nome" />!</div>
    </xsl:template>
</xsl:stylesheet>

Produrrebbe come risultato:


<div>Ho appena incontrato una persona: Mario!</div>
<div>Ho appena incontrato una persona: Paolo!</div>
<div>Ho appena incontrato una persona: Carlo!</div>

Ma andiamo più in profondità per meglio comprendere come funzionano i template. Finora i template usati hanno sempre avuto come oggetto (specificato nell'attributo match di xsl:template) l'elemento persona: ciò indicava all'elaboratore di gestire in sostanza l'intero documento senza tralasciare nulla, poiché specificando l'elemento persona venivano presi in considerazione anche tutti i nodi figli. Vediamo invece ora un esempio che si occupa di gestire solamente gli elementi nome e cognome:


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="nome">
        <div>Ho appena incontrato un nome: <xsl:value-of select="." />!</div>
    </xsl:template>
    <xsl:template match="cognome">
        <div>Ho appena incontrato un cognome: <xsl:value-of select="." />!</div>
    </xsl:template>
</xsl:stylesheet>

Per prima cosa bisogna notare che questa volta i template sono due: uno per gli elementi nome e uno per gli elementi cognome, questo significa che abbiamo indicato all'elaboratore come trattare solamente questi, vediamo dunque il risultato applicando questo foglio di stile al documento XML iniziale:


<div>Ho appena incontrato un nome: Mario!</div>
<div>Ho appena incontrato un cognome: Rossi!</div>
1,80 m75 Kgimpiegato
<div>Ho appena incontrato un nome: Paolo!</div>
<div>Ho appena incontrato un cognome: Rossi!</div>
1,75 m80 Kgdirigente
<div>Ho appena incontrato un nome: Carlo!</div>
<div>Ho appena incontrato un cognome: Rossi!</div>
1,90 m80 Kgmeccanico

Osservando questo risultato si dovrebbe intuire come il parser XSLT agisce di default: procede dal primo nodo fino all'ultimo, ovvero dall'alto verso il basso. Per primi incontra gli elementi nome e cognome, e agisce secondo le direttive che gli abbiamo dato nel foglio di stile, ma in seguito incontra gli elementi altezza, peso e professione. Non sapendo come comportarsi assume un comportamento di default, ovvero mostra i nodi di testo. Sarebbe sempre meglio non lasciare gestire nulla all'elaboratore XSLT come abbiamo fatto in questa occasione poiché produce spesso risultati indesiderati.

XSL:APPLY-TEMPLATES
Richiamare un template da un altro template.

Vediamo ora come con la direttiva xsl:apply-templates è possibile facilitare l'elaborazione di documento XML. Ecco un foglio di stile XSLT che ne fa uso:


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="persona">
        <div>
            Dati riguardanti il nome e il cognome del cliente:
            <xsl:apply-templates select="nome" />
            <xsl:apply-templates select="cognome" />
        </div>
    </xsl:template>
    <xsl:template match="nome">
        <div>Il nome di questo cliente è: <xsl:value-of select="." />!</div>
    </xsl:template>
    <xsl:template match="cognome">
        <div>Il cognome di questo cliente è: <xsl:value-of select="." />!</div>
    </xsl:template>
</xsl:stylesheet>

Seguiamo il processo che compie il nostro elaboratore XSLT: per prima cosa incontra un elemento persona, dunque va a vedere il template che lo riguarda, scrive nell'output la stringa "Dati riguardanti..." e poi si trova di fronte ad due elementi xsl:apply-templates, il primo che si riferisce a nome e il secondo a cognome; a questo punto come dice il nome della direttiva stesso (apply-templates) il parser applicherà i template che corrispondono all'espressione XPath contenuta nell'attributo select. Producendo quindi il seguente risultato:


<div>
    Dati riguardanti il nome e il cognome del cliente: 
    <div>Il nome di questo cliente è: Mario!</div>
    <div>Il cognome di questo cliente è: Rossi!</div>
</div>
<div>
    Dati riguardanti il nome e il cognome del cliente: 
    <div>Il nome di questo cliente è: Paolo!</div>
    <div>Il cognome di questo cliente è: Rossi!</div>
</div>
<div>
    Dati riguardanti il nome e il cognome del cliente: 
    <div>Il nome di questo cliente è: Carlo!</div>
    <div>Il cognome di questo cliente è: Rossi!</div>
</div>

In questo caso apply-templates è stato usato anche se non era del tutto necessario, sarebbe infatti bastato utilizzare la seguente sintassi sfruttando solamente un template:


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="persona">
        <div>
            Dati riguardanti il nome e il cognome del cliente:
            <div>Il nome di questo cliente è: <xsl:value-of select="nome" />!</div>
            <div>Il cognome di questo cliente è: <xsl:value-of select="cognome" />!</div>
        </div>
    </xsl:template>
</xsl:stylesheet>

In realtà usare diversi template con apply-templates risulta utile nel caso si debba riutilizzare più volte lo stesso schema per uno stesso tipo di elementi.

L'ATTRIBUTO MODE DI XSL:APPLY-TEMPLATES
Richiamare template differenti a seconda della necessità.

Vediamo brevemente un'altra potenzialità della direttiva XSLT apply-templates: l'attributo mode. Per uno stesso elemento (o più precisamente espressione XPath) è possibile avere template diversi che possono essere identificati attraverso l'attributo mode. Vediamo subito un esempio:


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="clienti">
        <html>
            <body>
                Indice dei clienti:
                <ul>
                    <xsl:apply-templates select="persona" mode="indice" />
                </ul>
                Messaggi per i clienti:
                <xsl:apply-templates select="persona" mode="messaggio" />
            </body>
        </html>
    </xsl:template>
    <xsl:template match="persona" mode="indice">
        <li><xsl:value-of select="nome" />&#xa0;<xsl:value-of select="cognome" /></li>
    </xsl:template>
    <xsl:template match="persona" mode="messaggio">
        <div>
            Buongiorno signor <ins><xsl:value-of select="cognome" />&#xa0;<xsl:value-of select="nome" /></ins>, 
            le ricordiamo che la sua altezza è di <ins><xsl:value-of select="altezza" /></ins> e 
            il suo peso di <ins><xsl:value-of select="peso" /></ins>.
            La sua occupazione è <ins><xsl:value-of select="professione" /></ins> e il suo codice fiscale 
            corrisponde a <ins><xsl:value-of select="@codicefiscale" /></ins>.
        </div>
    </xsl:template>
</xsl:stylesheet>

Nota: &#xa0; corrisponde a &nbsp; (non-breaking space, carattere il cui valore è 160, A0 in esadecimale) ma è espresso in questa forma perché non è possibile usare direttamente &nbsp; in quanto non è definito da alcuna parte (sebbene molto noto, esso fa in realtà parte delle specifiche HTML/XHTML, che in questo documento non entrano in gioco).

In questo foglio di stile abbiamo due template che si riferiscono all'elemento persona, ma che differiscono (oltre che per i contenuti) per il valore dell'attributo mode: rispettivamente indice e messaggio. Nel template di clienti (l'elemento radice del nostro documento di input) prima richiamiamo la versione del template di persona chiamata indice (attraverso xsl:apply-templates con mode uguale a indice) e in seguito la versione chiamata messaggio (sempre con xsl:apply-templates ma con mode con valore messaggio). In questo modo otteniamo un output articolato e che riutilizza gli stessi dati più volte:


<html>
    <body>
        Indice dei clienti: 
        <ul>
            <li>Mario&#xa0;Rossi</li>
            <li>Paolo&#xa0;Rossi</li>
            <li>Carlo&#xa0;Rossi </li>
        </ul>
        Messaggi per i clienti: 
        <div>
            Buongiorno signor <ins>Rossi&#xa0;Mario</ins>, le ricordiamo che la sua altezza è 
            di <ins>1,80 m</ins> e il suo peso di <ins>75 Kg</ins>. La sua occupazione è
            <ins>impiegato</ins> e il suo codice fiscale corrisponde a <ins>
            MRARSS50A01A390K</ins>.
        </div>
        <div>
            Buongiorno signor <ins>Rossi&#xa0;Paolo</ins>, le ricordiamo che la sua altezza è 
            di <ins>1,75 m</ins> e il suo peso di <ins>80 Kg</ins>. La sua occupazione è
            <ins>dirigente</ins> e il suo codice fiscale corrisponde a <ins>
            PLORSS50A01A390K</ins>. </div>
        <div>
            Buongiorno signor <ins>Rossi&#xa0;Carlo</ins>, le ricordiamo che la sua altezza è 
            di <ins>1,90 m</ins> e il suo peso di <ins>80 Kg</ins>. La sua occupazione è
            <ins>meccanico</ins> e il suo codice fiscale corrisponde a <ins>
            CRLRSS50A01A390K</ins>.
        </div>
    </body>
</html>

 

<< INDIETRO by VeNoM00