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:

Cascading Style Sheets (CSS), già definiti per l’HTML;
Document Style Semantics and Specification Language (DSSSL), legato all’SGML;
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:

href (obbligatorio),
type (obbligatorio),
title (opzionale),
media (opzionale),
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:

Construction Rules
Style Rules
Named Styles
Macros
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:

un Pattern che identifica l'elemento o il gruppo di elementi del sorgente per cui valgono quelle regole;
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:

<element type="capitolo">
<target-element type="titolo"/>
</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"

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

 

<regola>
<element type="paragrafo">
<target-element type="titolo"/>
</element>
</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:

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

 

<element type="capitolo">
<any>
<target-element type="titolo"/>
</any>
</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:

<target-element type="capitolo">
<attribute name="numero" value="primo"/>
</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:

<target-element type="capitolo">
<attribute name="numero" has-value="yes"/>
</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:

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

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

<titolo
space-before="12pt"
space-after="36pt"
font-weight="bold"
font-size="24pt">
<children/>
</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:

<children/> per processare tutti i figli dell'elemento;
<select-element> per processare un elemento;
<literal> per aggiungere testo;
<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:

<style-rule>
<target-element type="titolo"/>
<apply color="=red"/>
</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":

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

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

<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.