quaderni di usabilità TILS: Scuola Superiore Guglielmo Reiss Romoli

appuntamenti, strumenti di lavoro, personaggi, la rassegna stampa strumenti per approfondire gli argomenti scambia le tue idee ricerche bibliografiche, commenti e suggerimenti, libro degli ospiti consulta i quaderni

vai all'indice del quaderno n° 1

Architettura ed Evoluzione del World Wide Web

XSL: lo stile

Si è detto più volte della distinzione tra struttura e rappresentazione tipica di XML. Una volta definito il DTD, ovvero la struttura del documento, e quindi messo il parser in condizione di effettuare un controllo sintattico, è necessario associare al documento stesso un foglio di stile che ne descriva le regole relative alla rappresentazione da parte del processor. Queste non devono essere necessariamente univoche, ma devono poter variare al variare del dispositivo di output o anche in seguito all'interazione dell'utente. In linea di massima, non dicendo XML nulla delle regole di rappresentazione, si potrebbe usare una sintassi qualsiasi di stile. Le alternative possibili sono le seguenti:

punto elenco Cascading Style Sheets (CSS), già definiti per l’HTML;
punto elenco Document Style Semantics and Specification Language (DSSSL), legato all’SGML;
punto elenco Extensible Style Language (XSL), definiti nel contesto dell’XML.

XSL è il linguaggio "proprietario" del progetto XML. Sulla carta dovrebbe raccogliere i pregi di CSS e quelli di DSSSL, ovvero unire la semplicità alla potenza. Una prima bozza di lavoro è stata rilasciata il 18 agosto del 1998. L'associazione tra un documento XML e un foglio di stile avviene nel prologo del documento per mezzo del tag "xml:stylesheet", che ha come pseudo-attributi:

punto elenco href (obbligatorio),
punto elenco type (obbligatorio),
punto elenco title (opzionale),
punto elenco media (opzionale),
punto elenco charset (opzionale):

Ad esempio, con il tag:

<?xml:stylesheet href="stile.xsl" title="Compact" type="text/xsl"?>

si associa al documento un foglio di stile XSL "stile.xsl". E' possibile anche associare al file XML un foglio di stile alternativo attraverso l'istruzione "xml:alternate-stylesheet", che mantiene la stessa sintassi. I componenti principali di XSL sono:

punto elenco Construction Rules
punto elenco Style Rules
punto elenco Named Styles
punto elenco Macros
punto elenco Scripts

Con XSL l'output formattato è creato attraverso una operazione in due tempi: la creazione prima di una struttura ad albero, in cui viene associato ad ogni elemento lo specifico stile, e l'elaborazione definitiva di questa struttura ad albero. L'associazione tra gli elementi e la loro rappresentazione nel foglio di stile, che rappresenta il primo blocco fondamentale di XSL è specificato dalle "Construction Rules". Una Construction Rule consta di due elementi logici:

punto elenco un Pattern che identifica l'elemento o il gruppo di elementi del sorgente per cui valgono quelle regole;
punto elenco una Action che specifica l'albero da costruire quando il processor incontra quell'elemento o uno di quegli elementi.

Il Pattern identifica l'elemento del sorgente cui applicare la regola di costruzione, nel modo più semplice con il nome come valore dell'attributo type del tag <target-element>. Una Construction Rule contiene almeno un target-element, per cui il caso più semplice è il seguente:

< target-element type="titolo"/>

In questo esempio l'elemento "titolo" viene esclusivamente definito come destinatario della regola, a prescindere dalla sua posizione all'interno del documento, ovvero dovunque si trovi. Oltre al nome il Pattern può identificare gli elementi cui applicare la regola anche in modo più complesso, ovvero a seconda del suo contesto specifico in base ai rapporti di ascendenza e discendenza con altri elementi, agli attributi, alla posizione rispetto ad elementi fratelli. I rapporti gerarchici vengono definiti per mezzo dell'elemento <element>, il quale ha gli stessi attributi dell'elemento <target-element>, ma non indica l'elemento cui applicare la regola, bensì quello che rappresenta il contesto superiore dell'elemento cui applicare la regola. Pertanto, a differenza dell'esempio di prima, in questo caso:

punto elenco <element type="capitolo">
punto elenco <target-element type="titolo"/>
punto elenco </element>

la regola viene associata non più a tutti gli elementi "titolo", ma solo a quelli che hanno come ascendente "capitolo". Ovviamente questo permette la definizione di regole rappresentative diverse per lo stesso elemento in base alla sua posizione nella gerarchia struturale del documento. Nel seguente esempio l'elemento "titolo" ha un Pattern diverso, e quindi una diversa rappresentazione, a seconda che si trovi indentato dentro l'elemento "capitolo" o dentro l'elemento "paragrafo"

punto elenco <regola>
punto elenco <element type="capitolo">
punto elenco <target-element type="titolo"/>
punto elenco </element>
punto elenco </regola>

 

punto elenco <regola>
punto elenco <element type="paragrafo">
punto elenco <target-element type="titolo"/>
punto elenco </element>
punto elenco </regola>

L'elemento <element> sprovvisto dell’attributo type, che normalmente definisce l'ambito di applicabilità, e l'elemento <any> sono detti "wildcard". Il primo permette di associare il "target-element" alla regola purché nella stessa relazione gerarchica con il padre. Il secondo fa sostanzialmente la stessa cosa con la differenza che il target-element può trovarsi a qualsiasi livello di gerarchia. Ecco due esempi per questi due casi:

punto elenco <element type="capitolo">
punto elenco <element>
punto elenco <target-element type="titolo"/>
punto elenco </element>
punto elenco </element>

 

punto elenco <element type="capitolo">
punto elenco <any>
punto elenco <target-element type="titolo"/>
punto elenco </any>
punto elenco </element>

Nel primo esempio la regola è applicabile agli elementi "titolo" figli di un qualsiasi elemento figlio di "capitolo", nel secondo caso è invece applicabile agli elementi "titolo" che siano figli di un elemento che si trova ad un qualsiasi livello di gerarchia rispetto all'elemento "capitolo".

E' possibile poi vincolare l'associazione del Pattern all'elemento in base al valore assunto da un attributo dell'elemento stesso:

punto elenco <target-element type="capitolo">
punto elenco <attribute name="numero" value="primo"/>
punto elenco </target-element>

In questo caso la regola è applicata solamente agli elementi "capitolo" il cui attributo "numero" abbia valore "primo". Nel caso il valore dell'attributo "has-value" sia "yes" allora la regola si applica all'elemento a condizione che l'attributo abbia un valore qualsiasi e non si applica qualora non abbia nessun valore. Pertanto nel caso:

punto elenco <target-element type="capitolo">
punto elenco <attribute name="numero" has-value="yes"/>
punto elenco </target-element>

come si è detto l'applicabilità della regola all'elemento "capitolo" dipende dalla presenza o meno di un generico valore associato al suo attributo "numero".

Una volta identificati i Pattern associati agli elementi, viene invocata la seconda parte della Construction Rule, chiamata Action: dopo questa fase viene generata la struttura del "Flow object", ovvero la struttura del documento e insieme le regole per la formattazione. La Action comprende due tipi di elementi: i "flow objects" ed i "processing elements". I flow objects, che derivano da DSSSL, definiscono la formattazione, mentre i processing elements sono gli elementi di controllo. I flow object sono molto numerosi e tra gli altri i più comuni sono:

punto elenco <paragraph> che descrive un blocco di testo
punto elenco <display-group> che descrive un gruppo di blocchi
punto elenco <table> che descrive una tabella
punto elenco <external-graphic> che descrive un link ad un oggetto grafico
punto elenco <link> che descrive un link

Le caratteristiche dei flow object permettono di controllare la presentazione elencando le caratteristiche del tag. Ad esempio, la dichiarazione:

punto elenco <titolo
punto elenco space-before="12pt"
punto elenco space-after="36pt"
punto elenco font-weight="bold"
punto elenco font-size="24pt">
punto elenco <children/>
punto elenco </titolo>

genererebbe un tag titolo con una spaziatura superiore di 12 punti ed inferiore di 36, una dimensione di 24 punti e in grassetto. Le caratteristiche dei flow object possono essere ereditate o meno dagli oggetti figli.

Gli altri elementi della Action, i processing elements, servono per definire e controllare azioni relative al processo del documento, ovvero contengono informazione sul come applicare le Action al Pattern. Tra questi i più comuni sono:

punto elenco <children/> per processare tutti i figli dell'elemento;
punto elenco <select-element> per processare un elemento;
punto elenco <literal> per aggiungere testo;
punto elenco <eval> per aggiungere il risultato di uno script;

Per mezzo delle "Style Rule", definite dal tag <style-rule> è possibile attribuire ad un elemento più di una regola di formattazione. Come le Construction Rule, le Style Rule sono composte da Pattern e Action, ma la differenza è nel fatto che non generano un flow object e che si applicano a cascata su tutti gli elementi figli. Pertanto in un caso del genere:

punto elenco <style-rule>
punto elenco <target-element type="titolo"/>
punto elenco <apply color="=red"/>
punto elenco </style-rule>

all'elemento titolo si applica sempre un colore rosso, a prescindere da dove sia, per cui poi nelle successive Construction Rule non è più necessario definire il colore.

I Named Style sono dei gruppi di regole definiti da un nome che, richiamato come valore dell'attributo "use" durante la definizione di una Action permette l'applicazione a quell'elemento delle regole contenute nel gruppo. Pertanto, definendo in questo modo il Named Style "gruppo":

punto elenco <define-style name="gruppo"
punto elenco font-weight="bold"
punto elenco font-size="18pt"
punto elenco line-spacing="24pt"/>

questo può essere usato se si vuole rappresentare qualche elemento con quelle caratteristiche scrivendo semplicemente:

punto elenco

<paragraph use="gruppo">

Le macro, definite per mezzo dell’elemento <define-macro> permettono la costruzione di flow object complessi, mentre con <define-script> è possibile associare il risultato di una funzione ed usarlo per gestire dei controlli.