XML è un linguaggio derivato dall'SGML, da intendersi come un sottoinsieme «compatibile» con questo; in particolare, il nome rappresenta l'acronimo di Extensible markup language. Il motivo per il quale è stata introdotta questa variante dell'SGML è dovuto all'esigenza di trovare un compromesso tra l'SGML originale e l'HTML, che è solo un'applicazione di SGML troppo limitata per la documentazione multimediale. In pratica, l'intento è stato ed è quello di semplificare leggermente l'SGML rendendo disponibili molte qualità dell'SGML che un'applicazione rigida come l'HTML non è in grado di offrire.
In generale, un documento XML è un'applicazione di XML; nello stesso modo, l'HTML (come linguaggio) è un'applicazione SGML.
XML nasce come sottoinsieme di SGML, ma nel tempo si evolve e si allontana da SGML. In particolare, la prima caratteristica che comincia il distacco tra i due è costituita dai domini applicativi (namespace), i quali rendono difficile l'abbinamento di un DTD a un documento XML che ne fa uso.
La novità più importante di XML è l'utilizzo predefinito dell'insieme di caratteri universale, prevalentemente attraverso la forma UTF-8 e UTF-16. Questo fatto ha delle implicazioni importanti, in quanto i riferimenti a macro del tipo &n; e &xn; si fanno ai punti di codifica dello standard ISO 10646 (nel primo caso il numero è espresso in decimale, mentre nel secondo si tratta di un numero esadecimale).
XML non esclude a priori l'utilizzo di altri tipi di codifica; tuttavia, se non è possibile usare le codifiche UTF-n, per evitare ambiguità potrebbe essere conveniente limitarsi all'uso dell'ASCII tradizionale, dal momento che è perfettamente compatibile con la forma UTF-8. Eventualmente è possibile anche specificare il tipo di codifica attraverso un'istruzione apposita, che viene mostrata in seguito.
I commenti si indicano in linea di massima come in SGML, attraverso la forma:
<-- commento --> |
Come nell'SGML si deve evitare l'uso di due trattini in sequenza, --, ma in XML non è ammissibile il commento nullo nella forma <!>.
In XML, gli elementi devono essere aperti e chiusi correttamente attraverso i marcatori relativi; in pratica non è possibile più lasciare all'analizzatore XML il compito di determinare da solo la cosa in base al contesto. Questa limitazione è importante per facilitare il compito dei programmi che devono interpretare un documento XML e comunque si riflette positivamente nella struttura del sorgente del documento stesso.
Gli elementi vuoti vanno indicati regolarmente con il marcatore di chiusura, oppure con un solo marcatore speciale, che ha la forma seguente:
<nome_elemento/> |
In pratica, alla fine del marcatore appare una barra obliqua prima del simbolo >.
Di fatto, per problemi di compatibilità, si lascia uno spazio prima della barra finale. Per esempio: <hr />. |
L'assenza della possibilità di definire dei marcatori di apertura o di chiusura opzionali, fa sì che si semplifichi la dichiarazione di questi nel DTD:
<ELEMENT nome_elemento modello_del_contenuto > |
Nella figura 52.1 si vede un confronto tra la dichiarazione SGML e quella XML. Si vede chiaramente che in XML mancano le regole di minimizzazione.
In XML, i nomi che si attribuiscono agli elementi e agli attributi sono sensibili alla differenza tra lettere maiuscole e minuscole; per esempio, l'elemento testo è diverso dall'elemento Testo e da tutte le altre varianti possibili. Per la precisione, i nomi devono sottostare alle regole seguenti:
devono iniziare con una lettera alfabetica, oppure con un trattino basso (_, ovvero #x5F), e possono contenere anche cifre numeriche, il punto, il trattino basso e il trattino normale (#x2D);
non possono contenere spazi;
possono contenere i due punti (:), ma questa possibilità è comunque riservata a situazioni particolari (serve a definire un prefisso che rappresenta un contesto);
non possono iniziare con la sigla xml, o con qualunque altra variazione delle lettere minuscole e maiuscole, dal momento che questi potrebbero avere in seguito dei significati speciali.
Alcune entità standard essenziali sono predefinite e teoricamente non è necessario specificarle nel DTD. Si tratta di amp, lt, gt, apos e quot. Le macro relative sono &, <, >, ' e ".
Si può osservare questo particolare nella dichiarazione SGML di XML:
|
In XML, le entità parametriche possono essere utilizzate solo all'interno del DTD. Da ciò consegue logicamente che le sezioni marcate con le quali si può includere o escludere del testo in base al contenuto di un'entità parametrica, possono esistere solo nel DTD.
|
L'esempio mostra un pezzo di un DTD ipotetico, in cui vengono dichiarate due entità parametriche, bozza e finale. In questo caso, la macro %bozza; si traduce nella parola INCLUDE, mentre la macro %finale; si traduce nella parola IGNORE. In questo modo, viene dichiarato l'elemento libro nella prima modalità: quella che ammette la presenza dell'elemento commento.
XML ammette l'uso di un'altra sezione marcata soltanto, la sezione CDATA per delimitare del testo letterale.
|
L'esempio mostra in che modo sia possibile utilizzare letteralmente i simboli < e > in una sezione CDATA.
Le istruzioni di elaborazione sono una novità in XML. Servono in qualche modo per passare delle informazioni alle applicazioni. Si distinguono per avere la forma seguente:
<?istruzione_di_elaborazione?> |
Il testo che compone l'istruzione dipende dall'applicazione a cui è diretto. È importante tenere presente che tutto ciò che inizia con la stringa xml, assieme a tutte le sue variazioni di lettere maiuscole e minuscole, è riservato.
In generale, in base al significato che può avere l'istruzione di elaborazione, queste possono trovarsi in qualunque parte del sorgente XML.
Normalmente si inizia sempre un sorgente XML con un'istruzione di elaborazione che dichiara la versione di XML a cui si fa riferimento, assieme alla codifica utilizzata:
|
Nella descrizione fatta fino a questo punto sono già state presentate alcune convenzioni di XML che non sono esprimibili nella dichiarazione SGML relativa. In pratica, si tratta di regole che vanno tenute in considerazione quando si scrive un DTD per un documento XML. Vale la pena di raccogliere le convenzioni più importanti.
I nomi di elementi e degli attributi che iniziano per xml, con qualsiasi altra variante delle lettere maiuscole e minuscole, sono riservati.
Gli elementi che ne possono avere bisogno, devono poter disporre di un attributo denominato xml:space, a cui possano essere assegnate le parole chiave default o preserve. Il suo scopo è quello di definire il comportamento nei confronti degli spazi (di tutti i caratteri assimilabili a questo concetto). Assegnando la parola chiave default si intende lasciare che gli spazi vengano gestiti come al solito, eliminando quelli superflui; con la parola chiave preserve si vuole richiedere di mantenere gli spazi come sono. La dichiarazione di questo attributo può avvenire nel DTD come nell'esempio seguente:
|
In particolare, un elemento che per sua natura deve rispettare le spaziature originali, potrebbe essere definito nel modo seguente, dove si vede il caso dell'elemento pre di XHTML:
|
Gli elementi che ne possono avere bisogno, devono poter disporre di un attributo denominato xml:lang, a cui poter assegnare un codice identificativo del linguaggio contenuto. Si prevede l'uso di diversi tipi di codice:
un codice di linguaggio composto da due lettere, secondo lo standard ISO 639 (tabella 13.4);
un codice di linguaggio registrato dall'autorità IANA (Internet assigned numbers authority), a cui va aggiunto comunque il prefisso i-, oppure I-;
un codice stabilito dall'utente o concordato tra le parti, a cui va aggiunto il prefisso x-, oppure X-.
La dichiarazione di questo attributo può avvenire nel DTD come nell'esempio seguente:
|
Eventualmente si può anche specificare un linguaggio predefinito, come si vede nell'esempio seguente:
|
Possono esistere due livelli di approccio all'XML da parte dei programmi che lo utilizzano: il primo si limita a leggere il documento senza sapere nulla della sua struttura stabilita nel DTD; il secondo invece richiede la conoscenza di questa struttura. Nel primo caso è sufficiente che il documento XML sia stato scritto correttamente dal punto di vista formale, in senso generale; in questo modo si parla di well formed document. Nel secondo caso è importante che il documento, oltre che essere corretto dal punto di vista formale, sia anche valido in base alla definizione stabilita nel DTD.
Il documento XML corretto dal punto di vista formale, ha le caratteristiche seguenti:
contiene un elemento principale unico, all'interno del quale vanno collocati tutti gli altri (si parla comunemente dell'elemento root, ovvero della radice);
tutti i marcatori degli elementi devono essere indicati in modo corretto, attraverso degli annidamenti ordinati;
tutti gli elementi devono essere delimitati correttamente, senza saltare dei marcatori, inoltre gli elementi vuoti vanno chiusi oppure vanno indicati con il marcatore speciale già mostrato;
devono essere rispettate le regole stabilite per i nomi degli elementi;
i valori associati agli attributi vanno delimitati sempre attraverso apici doppi oppure apici singoli;
Il documento XML valido, oltre a essere corretto formalmente, deve anche essere conforme al DTD. Come nell'SGML normale, il DTD può essere indicato attraverso un riferimento, oppure può essere incorporato all'inizio del documento.
Il pacchetto SP di James Clark può essere utilizzato anche per convalidare un documento XML, a partire dal suo DTD (il procedimento è analogo a quanto già mostrato nella sezione 51.2); tuttavia, è necessario procurarsi la dichiarazione XML, che si può trovare nell'archivio dei sorgenti di SP stesso: pubtext/xml.dcl
.
Supponendo di disporre del file xml.dcl
nella directory corrente, si può realizzare un catalogo molto semplice come quello seguente:
|
Naturalmente, nel catalogo si possono aggiungere anche altre cose, in base alla necessità o meno di indicare il DTD e le entità generali. Per verificare il funzionamento della cosa, si può provare a eseguire la convalida dell'esempio seguente, che include il DTD nel preambolo e non ha bisogno di entità generali:
|
Si può osservare che si tratta di un documento elementare, in cui esiste solo l'elemento principale, denominato esempio.
Per la convalida, si può usare l'eseguibile nsgmls nel modo seguente:
$
nsgmls -c catalogo.xml -s esempio.xml
[Invio]
Qui si sottintende che il file del catalogo sia catalogo.xml
e che il sorgente XML sia contenuto nel file esempio.xml
. Se oltre alla convalida si vuole avere il risultato pre-elaborato, si toglie l'opzione -s, ottenendo quanto segue:
|
Con il termine dominio applicativo si vuole qui fare riferimento a quello che è noto come namespace a proposito di XML. Si definisce un dominio applicativo associando elementi, ma eventualmente anche attributi, a qualcosa che viene identificato tramite un indirizzo URI (sia URL, sia URN; si veda anche la sezione 54.1 a proposito dell'estensione del termine URI). Questa associazione ha lo scopo di evitare ambiguità, quando per qualche ragione si utilizzerebbero elementi o attributi con lo stesso nome, ma con significati differenti.
Dal momento che non è possibile utilizzare nomi di elementi e di attributi che contengano direttamente un URI, si associa questo URI attraverso un attributo particolare:
|
Questo esempio mostra l'utilizzo di MathML all'interno di un documento XHTML (le righe dalla settima alla nona). Si può osservare che l'elemento html, alla riga numero due dell'esempio, contiene l'attributo xmlns a cui è associata la stringa http://www.w3.org/1999/xhtml. Questa dichiarazione specifica che all'elemento html e a tutti i suoi discendenti si associa il dominio applicativo http://www.w3.org/1999/xhtml. Questo indirizzo (http://www.w3.org/1999/xhtml) è solo un punto di riferimento univoco; se si vuole, lo si può anche visitare (figura 52.14), ma ha soltanto lo scopo di dichiarare che gli elementi a cui è associato si riferiscono a XHTML; inoltre, non è nemmeno necessario che esista veramente.
Con i linguaggi SGML, si usa normalmente la dichiarazione del DTD a cui si fa riferimento. Anche con XML, volendo, è corretto usare un riferimento al DTD con l'istruzione <DOCTYPE...>, ma si inserisce questo concetto nuovo del dominio applicativo. |
Continuando a leggere l'esempio mostrato, alla settima riga appare l'elemento math, che, come dichiarato dall'attributo xmlns appartiene al dominio applicativo http://www.w3.org/1998/Math/MathML/; in pratica, dichiara che l'elemento in questione e ciò che contiene riguarda MathML.
Quanto visto in questo esempio, rappresenta un uso «predefinito» del dominio applicativo. Infatti, esiste anche la possibilità di associare gli elementi (e gli attributi) a un dominio applicativo, specificando un prefisso:
|
In questo caso si può osservare, alla riga numero uno, che l'elemento xsl:stylesheet contiene l'attributo xmlns:xsl, a cui è associato un URI. Ciò significa che, nell'ambito del controllo dell'elemento xsl:stylesheet, elementi e attributi il cui nome inizia con il prefisso xsl: appartengono al dominio applicativo http://www.w3.org/1999/XSL/Transform; per la precisione, anche lo stesso elemento xsl:stylesheet appartiene a questo dominio applicativo, proprio perché anche il suo nome inizia con il prefisso xsl:.
|
Questo nuovo esempio mostra l'uso di due domini applicativi, associati rispettivamente ai prefissi xsl: e fo: (le righe tre e quattro). La dichiarazione dei domini applicativi avviene nell'elemento principale, ovvero xsl:stylesheet (che appartiene al dominio applicativo associato al prefisso xsl:), in modo che possa essere valida per tutto il documento, salva la possibilità di modificarla all'interno di elementi ben precisi.
Oltre ai modi mostrati in questi esempi, esistono altre combinazioni; per esempio è possibile affiancare un dominio applicativo predefinito a domini specificati attraverso l'uso di prefissi. Tuttavia si preferisce evitare di creare troppa confusione su un concetto che invece dovrebbe essere semplice, per consentire la comprensione di altri concetti legati a XML. Eventualmente si possono consultare i documenti annotati nella bibliografia al termine del capitolo, per una visione più precisa e dettagliata a proposito dei domini applicativi (ovvero namespace).
La presenza dei domini applicativi rende difficile l'abbinamento di un DTD a un documento XML, perché i prefissi devono essere previsti esattamente nel DTD, come parte dei nomi degli elementi e degli attributi, mentre la definizione di un dominio applicativo consentirebbe l'utilizzo di un prefisso libero, deciso nel momento in cui si usa l'attributo xmlns:x.
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. Qui viene mostrato l'uso di Xalan (sezione 52.2.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:
/ /relazione /relazione/@lang /relazione/titolo /relazione/data /relazione/contenuto /relazione/contenuto/paragrafo /relazione/contenuto/paragrafo /relazione/contenuto/firma |
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 52.22 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 52.1.11). 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 52.22; 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.
XSL-FO (XSL formatting object) è un linguaggio realizzato in forma di file XML, con il quale si definisce l'aspetto finale di un documento. In pratica assomiglia concettualmente a HTML o a XHTML, con la differenza che vengono specificati in modo abbastanza preciso i dettagli sulla sua impaginazione per la stampa e generalmente sul suo aspetto finale.
XSL-FO nasce per essere utilizzato prevalentemente nell'ambito di un foglio di stile XSLT, con il quale si definisce la trasformazione di un documento XML in un file XSL-FO. Teoricamente, un navigatore dovrebbe essere in grado di utilizzare direttamente un foglio di stile XSLT che definisce questo tipo di trasformazione; in pratica, inizialmente si esegue la trasformazione per ottenere un file XSL-FO, il quale poi viene convertito in un formato finale comune (di solito è il formato PDF).
Nelle sezioni successive vengono mostrati prevalentemente esempi di file scritti secondo il formato XSL-FO, senza usare un foglio di stile XSLT, utilizzando FOP come programma per l'elaborazione, allo scopo di produrre il formato finale per la stampa.
Per poter ottenere la composizione finale di un file in formato XSL-FO occorre un elaboratore FO che generi un altro file più adatto alla consultazione e alla stampa. Qui viene mostrato l'uso di FOP,(2) che assieme a Xalan fa parte del progetto XML di Apache.
A differenza di Xalan, FOP è disponibile solo come programma Java, da interpretare anche una volta compilato. Gli esempi mostrati in questo capitolo sono stati verificati con FOP, eseguito attraverso Kaffe(3).
Una volta installato FOP in un sistema GNU, dovrebbe essere disponibile uno script che consente di avviare il programma senza difficoltà:
fop [opzioni] [-fo|-xml] file_ingresso [-xsl file_xsl] \ |
Se non fosse disponibile questo script, lo si potrebbe riprodurre facilmente utilizzando un contenuto simile a quello seguente:
|
Come si può intendere, in questo caso si considera che i file Java di FOP e di Xalan siano contenuti nella directory /usr/share/java/
; inoltre, viene considerato il contenuto della variabile di ambiente JAVA_OPTS per le opzioni da passare all'interprete Java. Infine, per quanto riguarda le prove effettuate, java è in realtà un collegamento all'eseguibile che svolge il compito di interpretazione dei programmi Java (per esempio /usr/lib/kaffe/bin/java
, oppure /usr/bin/kaffe
).
Per verificare subito il funzionamento di FOP si può provare con il sorgente XSL-FO seguente:
|
Supponendo che si tratti del file prova.fo
, si può generare la sua composizione con il comando seguente:
$
fop -fo prova.fo -pdf prova.pdf
[invio]
Utilizzando Kaffe come interprete Java è probabile che appaiano molti errori non gravi; a parte questi, ciò che si dovrebbe vedere durante la composizione sono i messaggi seguenti:
[INFO] FOP 0.20.4 [INFO] building formatting object tree [INFO] [1] [INFO] Parsing of document complete, stopping renderer |
Se non si arriva a vedere la frase finale in cui si conferma la conclusione dell'analisi e della composizione, qualcosa è andato storto. Quello che si deve ottenere è quindi il file prova.pdf
, contenente la scritta «Ciao a tutti.», collocata a partire dall'angolo superiore sinistro del foglio, senza alcun margine (il foglio dovrebbe avere il formato Lettera, ovvero 8,5 in × 11 in).
A parte la facilità con cui è stato utilizzato FOP per questo esempio, si possono presentare problemi difficili da comprendere, perché FOP è un progetto ancora all'inizio del suo sviluppo e non genera informazioni sufficienti a trovare gli errori sintattici nel sorgente XSL-FO. Per esempio, nel momento in cui si scrive questo capitolo, se si commette un piccolo errore come quello seguente (alla quarta riga, il marcatore iniziale dell'elemento fo:simple-page-master non è concluso dal simbolo >), i messaggi di XSL-FO non aiutano a capirlo:
|
$
fop -fo prova.fo -pdf prova.pdf
[invio]
[INFO] FOP 0.20.4 [INFO] building formatting object tree [ERROR] Can't find bundle for base name \ |
Date le difficoltà, può essere conveniente l'abbinamento con un DTD, da verificare prima della composizione; eventualmente si può usare quello presentato nella sezione 52.3.4. Purtroppo il DTD non può verificare tutti i vincoli reali del formato XSL-FO, ma almeno consente di evitare errori grossolani.
Se si salva il file del DTD con il nome fo.dtd
, nella directory corrente, si può modificare l'intestazione dei file XSL-FO nel modo seguente:
|
Per l'analisi sintattica si può usare il pacchetto SP di James Clark (come descritto nella sezione 51.2), ma prima occorre procurarsi anche una dichiarazione XML standard assieme al suo catalogo. Si suppone di avere così anche i file xml.dcl
e xml.cat
(si riveda eventualmente quanto spiegato all'inizio del capitolo), entrambi collocati nella directory corrente, assieme al DTD. Naturalmente il file xml.cat
deve contenere un riferimento al file xml.dcl
nella directory corrente:
|
Per avviare la verifica del file prova.fo
che contiene la dichiarazione corretta del DTD, si può procedere con il comando seguente:
$
cat prova.fo | nsgmls -s -c ./xml.cat
[invio]
Data questa premessa, negli esempi proposti di file XSL-FO viene inserita sempre l'intestazione che dichiara il DTD (salvo eccezioni), anche se si tratta di un'informazione superflua per la composizione. |
Un foglio di stile XSL-FO è un documento XML abbinato al dominio applicativo (namespace) http://www.w3.org/1999/XSL/Format, a cui si associa normalmente il prefisso fo:. L'elemento principale di questo documento, ovvero quello che contiene tutti gli altri, è fo:root:
|
Questo elemento contiene obbligatoriamente fo:layout-master-set e uno o più elementi fo:page-sequence. Il primo serve a descrivere la pagina e l'impaginazione generale, mentre il secondo serve a incorporare il contenuto di ciò che si vuole stampare effettivamente (il testo, le immagini, ecc.):
|
Prima di poter descrivere la struttura della pagina secondo XSL-FO, è necessario comprendere alcuni concetti generali legati alla gestione dei margini: i «blocchi», ovvero gli oggetti che per loro natura possono essere considerati come dei rettangoli, ovvero delle scatole bidimensionali, hanno una gestione comune dei margini. Si osservi la figura 52.65.
La figura mostra due scatole con margini definiti attraverso gruppi differenti di attributi: margin-top, margin-bottom, margin-left e margin-right; space-before, space-after, start-indent e end-indent. Il primo gruppo di attributi riguarda letteralmente il margine superiore, il margine inferiore, il margine sinistro e il margine destro, mentre il secondo gruppo tiene conto della direzione della scrittura. In pratica, la figura mostra l'uso del secondo gruppo di attributi quando la scrittura avviene da sinistra a destra e dall'alto in basso; si può comprendere intuitivamente come cambino significato questi margini se l'andamento della scrittura cambia.
Questi due gruppi di definizione dei margini sono alternativi e se si usano assieme, viene scelto un tipo di margine in base a delle precedenze. Tuttavia, in generale è meglio usare il secondo gruppo di margini che è più generale.
Per quanto riguarda la direzione, questa può essere controllata con l'attributo writing-mode, a cui si possono attribuire stringhe come lr-tb e rl-tb (in questo caso riferite rispettivamente alla scrittura da sinistra a destra e dall'alto in basso, oppure da destra a sinistra e dall'alto in basso). Tuttavia, è probabile che gli strumenti di elaborazione di file XSL-FO, nel loro sviluppo iniziale, non siano in grado di adeguarsi al cambiamento di direzione.
All'indirizzo allegati/sgml/fo.dtd è disponibile un DTD realizzato appositamente durante lo studio che ha preceduto la realizzazione degli esempi che sono proposti in questi capitoli, attingendo dalle informazioni contenute nel documento xsl:fo short reference, il quale fa parte della documentazione di FOP, oltre che dal documento Extensible stylesheet language (XSL), presso http://www.w3.org/TR/xsl/.
Si osservi che nel DTD manca la possibilità di utilizzare attributi generici riferiti ai bordi (per esempio border, border-color, ecc.), la presenza dei quali risulterebbe in un errore. Si ritiene che non sia il caso di utilizzare queste proprietà complessive come si può fare con i fogli di stile CSS; tuttavia, non sarebbe difficile aggiungere tali proprietà al DTD se lo si ritiene necessario.
L'impaginazione secondo XSL-FO viene definita attraverso dei modelli a cui si fa riferimento per mezzo di un nome. Quando si dichiara il modello, l'elemento relativo utilizza l'attributo master-name; quando vi si fa riferimento, l'elemento utilizza l'attributo master-reference.
La definizione minima della pagina e del contenuto si ottiene con una struttura XSL-FO simile a quella seguente, dove però non sono ancora stati annotati gli attributi obbligatori:
|
All'interno di fo:layout-master-set si collocano gli elementi che descrivono le caratteristiche delle pagine. Nella situazione più semplice si usano elementi fo:simple-page-master, all'interno dei quali si definiscono delle «regioni»:
<fo:simple-page-master master-name="nome_tipo_impaginazione" [page-height="altezza_pagina"] [page-width="ampiezza_pagina"] [writing-mode="direzione"] [space-before="spazio_prima"] [space-after="spazio_dopo"] [start-indent="rientro_iniziale"] [end-indent="rientro_finale"] [altri_attributi]> regioni </fo:simple-page-master> |
Il significato degli attributi mostrati nello schema è abbastanza intuitivo (in modo particolare il problema dei margini delle scatole è già descritto nella sezione 52.3), a parte l'attributo obbligatorio master-name, che ha lo scopo di dare un nome al tipo di impaginazione che viene dichiarato in quel contesto. Successivamente, quando si descrivono le componenti del corpo della pagina, viene fatto riferimento a questo nome per richiamare il tipo di impaginazione desiderato.
All'interno dei margini fissati con gli attributi appropriati dell'elemento fo:simple-page-master si collocano delle regioni, dichiarate attraverso gli elementi fo:region-before, fo:region-after, fo:region-start, fo:region-end e fo:region-body.
Guardando la figura 52.67, che rappresenta lo spazio interno ai margini di una pagina, si deve osservare che la scatola definita dall'elemento fo:region-body contiene, sovrapposte, le altre quattro regioni. Inoltre, è importante osservare i nomi delle regioni, che rappresentano una collocazione relativa alla direzione della scrittura; per esempio, con una scrittura che procede dal basso verso l'altro, si scambiano di posto le regioni fo:region-before e fo:region-after rispetto alla figura; inoltre, una scrittura che procede da destra verso sinistra fa sì che si scambi la collocazione delle regioni dichiarate dagli elementi fo:region-start e fo:region-end.
<fo:region-body [space-before="spazio_prima"] [space-after="spazio_dopo"] [start-indent="rientro_iniziale"] [end-indent="rientro_finale"] [writing-mode="direzione"] [reference-orientation="rotazione"] [altri_attributi] /> |
<fo:region-{before|after|start|end} extent="dimensione" [writing-mode="direzione"] [reference-orientation="rotazione"] [altri_attributi] /> |
Gli elementi che dichiarano le regioni sono vuoti. A esclusione dell'elemento fo:region-body, gli altri hanno tutti un attributo obbligatorio che ne definisce l'estensione (l'ampiezza per fo:region-start e fo:region-end; l'altezza per fo:region-before e fo:region-after).
Nei modelli sintattici mostrati appare un attributo che non è ancora stato preso in considerazione: reference-orientation. Con questo è possibile fa ruotare il contenuto, in multipli di 90 gradi, cosa che può risultare particolarmente utile per il contenuto delle regioni laterali.
Si comprende intuitivamente il significato di queste regioni che si trovano ai bordi del corpo della pagina: consentono di inserire delle intestazioni, dei piè di pagina, delle note a margine e simili. Ciò che è importante è rendersi conto che l'area che descrivono si sovrappone al corpo della pagina; pertanto, solitamente il contenuto che si va a inserire nel corpo viene controllato da margini ulteriori.
|
L'esempio che appare sopra mostra l'uso di un elemento fo:simple-page-master, con il quale si dichiara un tipo di impaginazione denominato normale, con le dimensioni di un foglio A4 (21 cm × 29,7 cm), con margini uguali di 2 cm, all'interno dei quali si trova un corpo, che a sua volta ha margini superiori e inferiori, pari all'estensione delle regioni rispettive.
Per riempire effettivamente le pagine di contenuti, occorre intervenire all'interno di elementi fo:page-sequence, con cui si fa riferimento al tipo di impaginazione che si vuole usare:
<fo:page-sequence master-reference="nome_tipo_impaginazione" [initial-page-number="numero_iniziale"] [force-page-count="auto"|"odd"|"even"|altro] [country="nazionalità_iso_3166"] [language="lingua_iso_639"] [altri_attributi]> contenuti </fo:page-sequence> |
Dal modello sintattico si vede che il riferimento al tipo di impaginazione si ottiene con l'attributo master-reference, che pertanto è obbligatorio. Sono inoltre da considerare gli attributi initial-number e force-page-count: il primo consente di stabilire il numero di pagina iniziale e il secondo permette di stabilire se il gruppo di pagine in questione deve essere complessivamente dispari, pari o se debbano essere rispettate altre regole.
Gli attributi country e language, nell'insieme servono a definire le caratteristiche locali del testo, stabilendo la nazionalità e il linguaggio. Formalmente, le sigle che si utilizzano per questo sono quelle definite nel documento RFC 1766, che in pratica corrisponde agli standard ISO 3166 (tabella 13.5) e ISO 639 (tabella 13.4).
Un elemento fo:page-sequence contiene necessariamente l'elemento fo:flow (uno solo), che a sua volta contiene ciò che viene distribuito nelle pagine (di solito il testo), come se fosse un flusso di informazioni. L'elemento fo:flow deve dichiarare, attraverso l'attributo flow-name, in quale regione della pagina si inserisce il flusso in questione:
<fo:flow flow-name="xsl-region-{body|before|after|start|end}" flusso </fo:flow> |
L'esempio seguente riprende quanto già presentato a proposito della dichiarazione del tipo di impaginazione, associato a un flusso che riguarda il corpo della pagina stessa:
|
Quello che si ottiene dalla trasformazione di questo file XSL-FO sono due pagine (l'ultima è bianca) che contengono il testo che si può vedere, suddiviso in due capoversi. Si può osservare che il margine superiore è di 3 cm, perché 2 cm definiti dall'impaginazione si sommano al margine del corpo della pagina.
Le pagine ottenute sono due perché è stato richiesto espressamente di impiegare una quantità pari (even) di pagine con l'attributo force-page-content dell'elemento fo:page-sequence.
Se si tralasciano gli attributi, la sintassi completa di fo:page-sequence corrisponde al modello seguente:
<fo:page-sequence attributi> [<fo:title attributi> titolo </fo:title>] [<fo:static-content flow-name="regione"> contenuto_statico </fo:static-content>] ... <fo:flow flow-name="regione"> flusso </fo:flow> </fo:page-sequence> |
L'elemento fo:title consente di attribuire un titolo, che non fa parte, necessariamente, del risultato della composizione. Gli elementi fo:static-content si comportano in modo simile a fo:flow, per quanto riguarda la selezione della regione di competenza, ma servono per definire del testo che si vuole appaia su tutte le pagine (come può essere per una riga di intestazione o alla base della pagina).
L'esempio seguente espande quanto già visto in quello precedente, aggiungendo un'intestazione e una riga a piè pagina, dove, in particolare, viene collocato anche il numero della pagina. Ovviamente, per poter apprezzare il fatto che l'intestazione e il piè di pagina rimangono costanti, occorre mettere qualcosa di più nel corpo:
|
Si osservi che gli esempi devono essere salvati in file con codifica UTF-8, altrimenti diventa indispensabile usare delle entità che facciano riferimento al punto di codifica, quando si usano simboli al di sopra di U+007F. Pertanto, se necessario, anche il commento va scritto nel modo corretto, per non creare problemi al programma che lo elabora:
|
Oppure:
|
Nella sezione precedente è stata mostrata la possibilità di richiedere espressamente una quantità pari o dispari di pagine per una certa sequenza di pagine. Tuttavia questo non basta per controllare l'estetica di un bel libro, perché di solito si vuole che le pagine cambino impostazione in modo automatico all'inizio di un capitolo. Per raggiungere risultati come questo, al posto di usare l'elemento fo:simple-page-master, si usa piuttosto fo:page-sequence-master, che però si avvale in pratica delle dichiarazioni di altri elementi fo:simple-page-master:
<fo:page-sequence-master master-name="nome_tipo_impaginazione"> [<fo:single-page-master-reference master-reference=nome_tipo_impaginazione />] [<fo:repeatable-page-master-reference master-reference=nome_tipo_impaginazione [maximum-repeat=max_ripetizioni] />] [<fo:repeatable-page-master-alternatives [maximum-repeat=max_ripetizioni]> <fo:conditional-page-master-reference master-reference="nome_tipo_impaginazione" page-position="posizione" [altri_attributi] /> ... </fo:repeatable-page-master-alternatives>] ... </fo:page-sequence-master> |
Inizialmente, l'insieme è piuttosto complesso. L'elemento più esterno, fo:page-sequence-master definisce un tipo di impaginazione a cui in seguito è possibile fare riferimento. All'interno di questo elemento possono apparire tre tipi di elementi, anche ripetutamente, con lo scopo di descrivere in sequenza i tipi di pagina da usare.
L'elemento fo:single-page-master-reference, che si riferisce a un certo tipo di pagina in base all'attributo master-reference, stabilisce che deve apparire una sola pagina con quelle caratteristiche. L'elemento fo:repeatable-page-master-reference stabilisce di utilizzare un certo tipo di pagina, attraverso l'attributo master-reference, per una quantità imprecisata di pagine (salvo l'uso dell'attributo maximum-repeat. Si osservi l'esempio seguente:
|
Questa volta vengono dichiarati due tipi di impaginazione «semplice»; una denominata normale, l'altra denominata speciale (righe da 5 a 31). La differenza tra i due tipi di impaginazione sta nell'assenza, nel secondo caso, della regione superiore, con la conseguente assenza del margine superiore nel corpo. In questo modo, si vuole fare sì che un capitolo utilizzi come prima pagina questo secondo tipo di impaginazione, senza usare la riga di intestazione. Pertanto, si definisce un tipo di impaginazione più complesso, denominato proprio capitolo, che prevede come prima pagina l'impaginazione speciale e come pagine successive l'impaginazione normale. Per quanto riguarda l'elemento fo:page-sequence nulla è cambiato rispetto all'esempio precedente.
Per ottenere effetti più complessi si può usare l'elemento fo:repeatable-page-master-alternatives, che contiene necessariamente elementi fo:conditional-page-master-reference:
<fo:repeatable-page-master-alternatives [maximum-repeat=max_ripetizioni]> <fo:conditional-page-master-reference master-reference="nome_tipo_impaginazione" page-position="first"|"last"|"rest"|"any" [altri_attributi] /> ... </fo:repeatable-page-master-alternatives> |
In pratica, attraverso gli elementi conditional-page-master-reference si vanno a individuare dei sottogruppi di pagine in base a una condizione. La sintassi mostra la selezione più semplice, attraverso l'attributo page-position, con il quale si può individuare la prima pagina, l'ultima, le pagine successive alla prima oppure qualunque pagina. Tuttavia sono disponibili altri attributi per condizioni più sofisticate, che qui non vengono descritti. L'esempio seguente svolge lo stesso lavoro di quello precedente, con l'uso di queste selezioni condizionali:
|
La differenza rispetto all'esempio precedente si trova precisamente nelle righe da 29 a 38.
A proposito del contenuto del documento, è già stato mostrato l'uso e la struttura successiva all'elemento fo:page-sequence:
<fo:page-sequence master-reference="nome_tipo_impaginazione" [initial-page-number="numero_iniziale"] [force-page-count="auto"|"odd"|"even"|altro] [country="nazionalità_iso_3166"] [language="lingua_iso_639"] [altri_attributi]> [<fo:title attributi> titolo </fo:title>] [<fo:static-content flow-name="regione"> contenuto_statico </fo:static-content>] ... <fo:flow flow-name="regione"> flusso </fo:flow> </fo:page-sequence> |
L'elemento fo:page-sequence rappresenta letteralmente una sequenza di pagine, come potrebbe essere un capitolo o una parte di un libro, dove, tra le altre cose, può essere utile ripartire con una nuova numerazione delle pagine. Pertanto, un documento può avere più elementi fo:page-sequence distinti.
Gli elementi fo:flow, o fo:static-content, rappresentano in pratica la destinazione del contenuto, che va inserito nella regione appropriata. Questi elementi possono contenere dei «blocchi», o più precisamente elementi fo:block, fo:block-container, fo:list-block, fo:table, fo:table-and-caption.
L'elemento fo:block ha la particolarità di contenere sia testo lineare, sia altri blocchi (quindi anche se stesso). Pertanto viene usato indifferentemente come un equivalente dell'elemento DIV o dell'elemento P di HTML.
Il contenuto di una regione del corpo definita dall'impaginazione, è fatto sommariamente di blocchi, come l'elemento fo:block, e di componenti lineari, in base al contesto. Generalmente, un blocco non può essere contenuto in un contesto lineare, a meno che questo sia incorporato in un elemento apposito, come fo:inline-container.
Un blocco è idealmente un oggetto a due dimensioni, rettangolare, per il quale potrebbero essere previsti dei margini su tutti i lati; un componente lineare è invece inteso come un oggetto monodimensionale che può avere margini solo prima e dopo.
In generale, gli elementi che descrivono un blocco o una componente lineare condividono delle opzioni comuni per definire i margini, il bordo, il colore di fondo e altre caratteristiche. La tabella 52.77 elenca alcuni attributi abbastanza comuni.
|
Le sezioni successive non esauriscono l'argomento trattato, perché diversi elementi e molti attributi non vengono descritti affatto. Per ottenere le informazioni mancanti e in modo più dettagliato, si consulti la documentazione annotata nella bibliografia che appare alla fine del capitolo.
Un blocco di testo comparabile all'elemento P di HTML, si ottiene con l'elemento fo:block, che però può contenere anche altri blocchi, oltre al testo lineare puro e semplice:
<fo:block [attributi]> ... </fo:block> |
L'esempio seguente mostra l'uso di alcuni attributi per modificare il linguaggio, per inserire dei bordi, per modificare il carattere e per inserire dei margini:
|
Il risultato della composizione si può osservare nelle figura seguente:
Dal momento che tutti gli elementi fo:block dell'esempio utilizzano un carattere di 7 mm, si può sfruttare l'ereditarietà della proprietà, inserendo tutti questi blocchi in un elemento fo:block complessivo (riga 15) in cui si dichiara una volta sola tale dimensione:
|
Il risultato che si ottiene è lo stesso già visto nella figura precedente.
In un contesto lineare, si può inserire testo o elementi che non creano un blocco. In modo particolare, l'elemento fo:inline, con l'uso dei suoi attributi, consente di modificare le caratteristiche del testo, come il carattere, lo spostamento sulla linea di riferimento (apici e pedici) e il colore:
<fo:inline [font-family="nome"|"serif"|"sans-serif" |"cursive"|"fantasy"|"monospace"] [font-size="altezza"|"xx-small"|"x-small" |"small"|"medium"|"large"|"x-large" |"xx-large"|"larger"|"smaller" |"n%"|"nem"] [font-style="normal"|"italic"|"oblique" |"backslant"] [font-stretch="ultra-condensed"|"extra-condensed" |"condensed"|"semi-condensed" |"normal"|"semi-expanded" |"expanded"|"extra-condensed" |"ultra-expanded"] [font-variant="normal"|"small-caps"] [font-weight="normal"|"bold"|"bolder"|"lighter"] [baseline-shift="sub"|"super"|...] [color="colore"] [altri_attributi]> [contenuto_lineare] </fo:inline> |
L'esempio seguente mostra solo un estratto di un file XSL-FO, con un blocco che contiene testo lineare, all'interno del quale appaiono alcuni elementi fo:inline con lo scopo di modificare il carattere, il colore e lo spostamento verticale:
|
Nell'ambito di un contesto lineare, eccezionalmente, è possibile inserire un blocco, attraverso l'elemento fo:inline-container:
<fo:inline-container [width="ampiezza"] [altri_attributi]> [contenuto_blocco] </fo:inline-container> |
Gli elenchi sono definiti attraverso l'elemento fo:list-block, che è, evidentemente, un blocco:
<fo:list-block [attributi]> <fo:list-item [attributi]> <fo:list-item-label [attributi]> blocchi </fo:list-item-label> <fo:list-item-body [attributi]> blocchi </fo:list-item-body> <fo:/list-item> ... </fo:list-block> |
In pratica, l'elemento fo:list-block contiene obbligatoriamente elementi fo:list-item, i quali, a loro volta, contengono la coppia fo:list-item-label e fo:list-item-body. L'esempio seguente costruisce un elenco puntato molto semplice, dove i lembi che segnalano l'inizio di ogni punto sono costituiti da un asterisco:
|
Tuttavia, se si esegue la composizione si può osservare che gli asterischi si trovano a essere sovrapposti al corpo delle voci:
Per evitare che ciò accada, è necessario intervenire con dei rientri appropriati, utilizzando gli attributi dei blocchi che sono contenuti, sia come etichette, sia come corpo delle voci elencate. Per la precisione, si usa l'attributo end-indent nei blocchi delle etichette e l'attributo start-indent nei blocchi del corpo. Per fare in modo che queste distanze vengano calcolate automaticamente, si usano delle funzioni interne a XSL-FO, in grado di restituire il valore appropriato al contesto. Si tratta rispettivamente di label-end() e di body-start(). Pertanto, l'esempio va modificato come segue:
|
Questa volta il risultato della composizione è corretto:
Come si può immaginare, la realizzazione di una tabella con XSL-FO è un'operazione abbastanza complessa, anche nelle situazioni più semplici:
<fo:table-and-caption [attributi]> [<fo:table-caption [attributi]> blocchi </fo:table-caption>] <fo:table [table-layout="auto"..."fixed"] [altri_attributi]> [<fo:table-column [table-column="ampiezza"] [attributi] />] ... [<fo:table-header [attributi]> righe </fo:table-header>] [<fo:table-footer [attributi]> righe </fo:table-footer>] <fo:table-body [attributi]> righe </fo:table-body> </fo:table-caption> </fo:table-and-caption> |
Il significato dei vari elementi che appaiono nel modello sintattico dovrebbe essere intuitivo; si osservi in particolare che una tabella si può realizzare anche partendo soltanto dall'elemento fo:table, quando non è importante l'inserimento di una didascalia con l'elemento fo:table-caption. Le righe interne all'intestazione, al piè di pagina e al corpo, vengono inserite nel modo seguente:
<fo:table-row [attributi]> <fo:table-cell [attributi]> blocchi </fo:table-cell> </fo:table-row> |
L'ampiezza delle colonne, i bordi e altre caratteristiche della tabella vengono gestiti attraverso gli attributi. Teoricamente, l'elemento fo:table dispone dell'attributo table-layout, con il quale si potrebbe richiedere un adattamento automatico della larghezza delle colonne; in pratica questa funzionalità è abbastanza difficile da trovare, pertanto si è costretti a usare l'attributo column-width degli elementi fo:table-column.
L'esempio seguente mostra una tabella molto semplice e anche molto povera, perché manca qualunque bordo e perché viene definita senza l'elemento fo:table-and-caption, in modo da garantire il funzionamento con le prime edizioni di FOP:
|
Ecco il risultato:
Per introdurre dei bordi, almeno teoricamente, si può intervenire dal blocco contenuto nella singola cella, fino all'elemento fo:table più esterno; tuttavia, a seconda del programma di elaborazione che si utilizza, può darsi che in alcuni punti i bordi non vengano presi in considerazione.
L'inserzione di un'immagine si ottiene con l'elemento fo:external-graphic, che è vuoto e appartiene a un contesto lineare:
<fo:external-graphic> src="file"|"indirizzo_uri" [scaling="uniform"|"non-uniform"] [height="auto"|"altezza] [width="auto"|"larghezza] [altri_attributi] /> |
Se non si indicano delle dimensioni attraverso gli attributi height o width, l'immagine viene inserita alla sua dimensione naturale. Se si modifica una sola dimensione, normalmente si ottiene l'adattamento dell'altro valore in modo relativo; tuttavia, attraverso l'opzione scaling="non-uniform", è possibile deformare l'immagine.
Il file o l'indirizzo URI dell'immagine deve fare riferimento a un formato compatibile con le capacità elaborative del sistema usato per la composizione. Di solito vanno bene almeno i formati GIF e JPG.
|
L'esempio mostra l'inserzione della stessa immagine due volte, in modi differenti. In particolare, la seconda volta l'immagine viene centrata orizzontalmente per mezzo dell'attributo text-align dell'elemento fo:block che la contiene.
Si può realizzare facilmente una linea orizzontale con un elemento fo:block bordato, magari anche vuoto:
<fo:block border-after-style="stile" [border-after-width="spessore"] [border-after-color="colore"] [altri_attributi] /> |
Per inserire delle linee orizzontali in un contesto lineare, ovvero all'interno del testo, si usa l'elemento fo:leader:
<fo:leader leader-pattern="use-content" [leader-length="lunghezza"] [altri_attributi]> modello </fo:leader> |
<fo:leader leader-pattern="space"|"rule"|"dots" [leader-length="lunghezza"] [rule-style="stile"] [rule-thickness="spessore"] [altri_attributi] /> |
Se l'elemento contiene qualcosa e all'attributo leader-pattern viene associato il valore use-content, questo viene usato per costruire la linea (per esempio si potrebbe realizzare una linea fatta di asterischi o di sequenze più complesse). Tuttavia, di solito si vogliono realizzare soltanto linee continue, spezzate o puntate, pertanto l'elemento si usa prevalentemente vuoto.
È importante osservare che la linea che si ottiene raggiunge la fine dello spazio orizzontale disponibile, pertanto, per realizzare linee di collegamento come quelle degli indici, dove appare un titolo alla sinistra e un numero di pagina alla destra, occorre inserire tutto in una tabella. Nell'esempio seguente vengono mostrati diversi casi, compresa la simulazione di un indice elementare, inserito in una tabella:
|
Ecco il risultato della composizione dell'esempio:
XSL-FO ha una gestione molto sofisticata dei riferimenti ipertestuali; tuttavia, qui si vuole mostrare solo l'uso più semplice. In generale, la maggior parte degli elementi può contenere l'attributo id, con lo scopo di associare una stringa di identificazione univoca, in modo da consentire successivamente di raggiungere il contenuto di questi elementi attraverso un riferimento interno.
Per fare riferimento a qualcosa, si usa l'elemento fo:basic-link (nell'ambito di un contesto lineare), specificando se si tratta di un riferimento interno o esterno, con l'uso alternativo degli attributi internal-destination e external-destination:
<fo:basic-link {internal-destination="stringa_id"}\ |
Il testo contenuto nell'elemento serve per individuare la zona su cui funziona la selezione del riferimento, come nell'esempio seguente, dove la parola «qui» serve come superficie su cui fare un clic con il mouse:
|
Per fare riferimento a una pagina, in modo da ottenerne il numero nella composizione stampata, si usano due elementi per due situazioni differenti:
<fo:page-number [attributi] /> |
<fo:page-number-citation ref-id="stringa_a_cui_si_fa_riferimento" [attributi] /> |
Nel primo caso, si ottiene il numero della pagina corrente; nel secondo, si ottiene il numero di pagina a cui si fa riferimento con la stringa indicata con l'attributo ref-id. L'esempio seguente riassume l'uso di questi elementi, dove in particolare si inserisce il numero di pagina nella regione inferiore:
|
Ecco come potrebbe apparire il risultato della composizione:
Esistono due tipi di componenti che, nella composizione, non si collocano nella posizione in cui appaiono nel corso del documento. Si tratta di note a piè pagina e di oggetti fluttuanti. Le note a piè pagina si inseriscono nell'ambito di un contesto lineare e si ottengono con questa sintassi:
<fo:footnote> <fo:inline [attributi]> simbolo </fo:inline> <fo:footnote-body> blocchi </fo:footnote-body> </fo:footnote> |
In pratica, l'elemento fo:footnote contiene necessariamente un elemento fo:inline, il cui scopo è quello di inserire un simbolo o qualunque cosa serva per rinviare il lettore alla nota a piè pagina; subito dopo, l'elemento fo:footnote-body contiene uno o più blocchi che contengono la nota vera e propria. Si tenga in considerazione il fatto che, probabilmente, si vuole inserire all'inizio delle note lo stesso simbolo usato per il richiamo.
|
L'esempio mostra solo una porzione di un file XSL-FO, che, nella composizione finale potrebbe apparire in modo simile a questo:
Gli oggetti fluttuanti si inseriscono all'interno dell'elemento fo:float, che si comporta come un blocco:
<fo:float float="before"|"start"|"end"|... [clear="posizione"]> blocchi </fo:float> |
In pratica, con l'aiuto dell'attributo float si può stabilire in che modo debba essere collocato l'oggetto fluttuante, mentre l'attributo clear serve a definire un comportamento in prossimità di altri oggetti fluttuanti.
Non vengono mostrati esempi sull'uso di questo elemento, anche se si può intuire la sua importanza in presenza di immagini e piccole tabelle che è bene collocare in modo dinamico nel corpo di un documento.
Fino a questo punto, XSLT e XSL-FO sono stati descritti separatamente, per evitare confusione, mentre fanno parte di un sistema integrato. Una volta compreso il meccanismo di XSLT e di XSL-FO, non dovrebbe essere difficile unire le due cose per trasformare un documento XML in un file XSL-FO, allo scopo di arrivare poi alla composizione finale.
In precedenza è stato mostrato un file XML molto semplice, associando a questo la trasformazione in formati comuni:
|
Per trasformare questo tipo di file in un foglio di stile XSL-FO, si può usare un foglio di stile XSLT come quello seguente; si osservi anche la presenza della dichiarazione del dominio applicativo associato al prefisso fo:.
|
In questo caso la trasformazione genera il file XSL-FO seguente:
|
Il risultato della composizione:
|
Per il resto, si veda quanto già descritto in precedenza a proposito di XSLT nella sezione 52.2.
XMLTeX(4) è un sistema per comporre file XML attraverso TeX; PassiveTeX(5) è un insieme di fogli di stile aggiuntivi che, in particolare, consentono a XMLTeX di elaborare file XSL-FO.
XMLTeX è un sistema che si affianca normalmente a LaTeX per trasformare un file XML in un documento pronto per la stampa, attraverso un metodo di trasformazione degli elementi e degli attributi del file di origine in comandi di LaTeX. Per fare questo occorre predisporre un «file di configurazione» nel quale si dichiarano queste sostituzioni. Viene proposto il solito esempio di file XML molto semplice, dove in particolare l'attributo linguaggio contiene un nome valido per LaTeX:
|
Supponendo di dare a questo file il nome relazione.xml
, si può realizzare il file relazione.cfg
, con l'indicazione delle trasformazioni da apportare:
|
Come si vede si tratta di comandi TeX con cui si dichiarano gli abbinamenti tra elementi e attributi con comandi corrispondenti di LaTeX.
\XMLelement{nome_elemento}{[dichiarazione_attributi]}\ |
\XMLelement{nome_elemento}{[dichiarazione_attributi]}\ |
Il comando \XMLelement consente di dichiarare la trasformazione dei marcatori di un elemento in comandi LaTeX: gli ultimi due argomenti contengono rispettivamente il codice LaTeX di apertura e il codice di chiusura dell'elemento. Tuttavia, se nell'argomento destinato a ospitare il codice LaTeX di apertura si inserisce soltanto il comando \xmlgrab, si può mettere tutto nell'argomento finale, usando la sigla #1 per fare riferimento al contenuto dell'elemento.
Nel secondo argomento del comando \XMLelement si possono inserire comandi \XMLattribute per prelevare le informazioni sugli attributi:
\XMLattribute{nome_attributo}{nome_comando_tex}{[valore_predefinito]} |
Osservando l'esempio del file relazione.cfg
si può vedere che nella dichiarazione riferita all'elemento relazione appare l'associazione dell'attributo linguaggio al comando \mylanguageattribute, che poi viene usato successivamente. In pratica, il comando di LaTeX che nel file relazione.cfg
appare come la riga seguente, è come se venisse sostituito con quella successiva:
|
|
Nel file di configurazione, ovvero il file .cfg
, possono essere collocati altri comandi importanti; fortunatamente molte indicazioni essenziali fanno già parte della configurazione generale, che potrebbe trovarsi nel file /etc/texmf/xmltex/xmltex.cfg
. Eventualmente si può approfondire la cosa leggendo la documentazione originale di XMLTeX.
Disponendo del file di configurazione per la trasformazione del documento XML, prima di passare alla composizione con LaTeX, si deve realizzare un piccolo file di collegamento, denominato, in questo caso, relazione.tex
:
|
Si può passare così alla composizione di questo file relazione.tex
:
$
latex relazione.tex
[invio]
This is TeX, Version 3.14159 (Web2C 7.4.5) (./relazione.tex LaTeX2e <2001/06/01> Babel <v3.7h> and hyphenation patterns for american, french, german, ngerman, danish, dutch, finnish, greek, italian, latin, spanish, nohyphenation, loaded. (/usr/share/texmf/tex/xmltex/base/xmltex.tex xmltex version: 2002/06/25 v1.9 (Exp) Encoding = utf-8 (/usr/share/texmf/tex/xmltex/config/xmltex.cfg) (./relazione.cfg) (./relazione.xml Default: relazione linguaggio="" (/usr/share/texmf/tex/latex/base/article.cls Document Class: article 2001/04/21 v1.4e Standard LaTeX document class (/usr/share/texmf/tex/latex/base/size10.clo)) (/usr/share/texmf/tex/latex/base/fontenc.sty (/usr/share/texmf/tex/latex/cyrillic/ot2enc.def) (/usr/share/texmf/tex/latex/base/ot1enc.def)) (/usr/share/texmf/tex/generic/babel/babel.sty (/usr/share/texmf/tex/generic/babel/italian.ldf (/usr/share/texmf/tex/generic/babel/babel.def))) (./relazione.aux) (/usr/share/texmf/tex/latex/cyrillic/ot2cmr.fd) [1] (./relazione.aux) ) ) ) Output written on relazione.dvi (1 page, 692 bytes). Transcript written on relazione.log. |
Si ottiene così il file relazione.dvi
, da cui si può generare facilmente un file PostScript:
$
dvips -o relazione.ps relazione.dvi
[invio]
This is dvips(k) 5.92b Copyright 2002 Radical Eye Software (www.radicaleye.com) ' TeX output 2003.08.09:1533' -> relazione.ps <texc.pro><f7b6d320.enc><texps.pro>. <cmr10.pfb><cmbx12.pfb>[1] |
In modo analogo si può ottenere una composizione in formato PDF, utilizzando pdflatex:
$
pdflatex relazione.tex
[invio]
Eventualmente, entrambe le cose si possono fare in modo più semplice, senza bisogno di realizzare il file relazione.tex
, con i comandi seguenti, che servono a ottenere, rispettivamente, la composizione in formato DVI e PDF:
$
latex "&xmltex" relazione.tex
[Invio]
$
pdflatex "&pdfxmltex" relazione.tex
[Invio]
Nel caso dovessero essere presenti riferimenti incrociati, è necessario eseguire la composizione con LaTeX per tre volte di seguito (sempre con lo stesso comando). |
Per concludere viene mostrato il risultato della composizione dell'esempio:
|
Come accennato all'inizio del capitolo, PassiveTeX è un insieme di fogli di stile da usare con XMLTeX per comporre direttamente file XSL-FO, attraverso LaTeX. Viene ripreso un esempio già apparso in un altro capitolo di file XSL-FO:
|
In modo molto semplice, si arriva alla composizione di questo file con il comando seguente, supponendo che si tratti del file esempio-014.fo
:
$
latex "&xmltex" esempio-014.fo
[Invio]
In questo modo si genera il file esempio-014.dvi
, dal quale si può ottenere un file PostScript nel modo consueto:
$
dvips -o esempio-014.ps esempio-014.dvi
[Invio]
Ovviamente si può anche eseguire una composizione in formato PDF direttamente con il comando seguente:
$
pdflatex "&pdfxmltex" esempio-014.fo
[Invio]
Nel caso dovessero essere presenti riferimenti incrociati, sarebbe necessario eseguire la composizione con LaTeX per tre volte di seguito. |
Ecco il risultato della composizione:
W3C, Extensible Markup Language (XML) 1.0, http://www.w3.org/TR/REC-xml/
James Clark, Comparison of SGML and XML, http://www.w3.org/TR/NOTE-sgml-xml-971215.html
Peter Flynn, The XML FAQ, http://xml.silmaril.ie/
Norman Walsh, A Technical Introduction to XML, http://nwalsh.com/docs/articles/xml/
W3C, Namespaces in XML, http://www.w3.org/TR/REC-xml-names/
James Clark, XML namespaces, http://www.jclark.com/xml/xmlns.htm
O'Reilly, xml.com, http://www.xml.com
Cover Pages, http://xml.coverpages.org/xml.html
W3C, XSL Transformations (XSLT), http://www.w3.org/TR/xslt
W3C, XML Path Language (XPath), http://www.w3.org/TR/xpath
Elliotte Rusty Harold, XML Bible, http://rf4.us/lib/old/books/programming/XMLBible.pdf
Michele Sciabarrà, Tutorial XML/XSLT, http://www.corsojava.it/testi/xml/
Michele Sciabarrà, Linux e programmazione web, McGraw-Hill, 2001, ISBN 88-386-4177-3; in particolare il capitolo XML e XSLT
Apache software foundation, FOP, http://xmlgraphics.apache.org/fop/
W3C, Extensible stylesheet language (XSL), http://www.w3.org/TR/xsl/
W3C, Extensible stylesheet language, http://www.w3.org/TR/xsl/
Herong Yang, Herong's notes on XSL-FO and XHTML, http://www.herongyang.com/xhtml/
David Carlisle, xmltex: A non validating (and not 100% conforming) namespace aware XML parser implemented in TeX*, http://www.dcarlisle.demon.co.uk/xmltex/manual.html
Sebastian Rahtz, PassiveTeX, http://wayback.archive.org/web/*/http://www.tei-c.org/Software/passivetex
1) Xalan software libero con licenza speciale
2) FOP software libero con licenza speciale
3) Kaffe è un vecchio interprete di applicazioni Java, sviluppato prima che fosse rilasciato il pacchetto OpenJDK con una licenza libera. Attualmente, le distribuzioni GNU/Linux comuni dovrebbero disporre di una «macchina virtuale» Java, ed eventualmente di un ambiente di sviluppo Java, attraverso OpenJDK, GCJ e altri componenti liberi, senza complicazioni per l'utilizzatore.
5) PassiveTeX Software libero con licenza speciale