risorse | spazi in xml

Spazi in XML

Gli spazi nei documenti XML sono soggetti ad un trattamento peculiare tale da produrre risultati a prima vista sorprendenti. Ciò dipende dal fatto che lo standard XML riconosce che a volte è conveniente fare uso di spaziature per evidenziare la struttura del documento:

<message id="42" class="confidential">Lorem ipsum <emphasis type="important">dol
or</emphasis> sit amet:<list><item>consectetur adipiscing elit;</item><item>aene
an quis ipsum et leo laoreet congue</item></list>Fusce ultricies ut enim sit ame
t viverra.</message>

Fig. 1: flusso testuale di un documento XML.

<message id="42" class="confidential">Lorem ipsum
·<emphasis type="important">dolor</emphasis>
·sit amet:
··<list>
···<item>consectetur adipiscing elit;</item>
···<item>aenean quis ipsum et leo laoreet congue</item>
··</list>
·Fusce ultricies ut enim sit amet viverra.
</message>

Fig. 2: lo stesso documento, indentato.

Le due versioni del documento sono differenti, ma il contenuto informativo è equivalente. XML si fa carico di individuare questo tipo di spaziature non significative, sotto certe condizioni.

La spaziatura alla quale si sta facendo riferimento è quella del documento, non quella quella prevista dalla sintassi XML: la prima si trova al di fuori dei tag XML (indicata in rosso negli esempi), la seconda all'interno, evidenziata qui sotto in azzurro:

<message·id="42"·class="confidential">Lorem ipsum
 <emphasis·type="important">dolor</emphasis>
 sit amet:
  <list>
   <item>consectetur adipiscing elit;</item>
   <item>aenean quis ipsum et leo laoreet congue</item>
  </list>
 Fusce ultricies ut enim sit amet viverra.
</message>

Fig. 3: spaziature richieste dalla sintassi XML.

Riguardo alla gestione della spaziatura del documento, nello standard XML si legge:[7.b]:

An XML processor must always pass all characters in a document that are not markup through to the application.

In altre parole, «ciò che non è markup è un dato», e di conseguenza sembrerebbe che nessun carattere che si trovi al di fuori dei tag venga trascurato, nemmeno gli spazi. In realtà, non è proprio così… Prima di proseguire, però, è bene stabilire con precisione cosa XML considera spazio.

Caratteri di spaziatura

L'insieme dei caratteri di spaziatura contemplati da XML si deduce dalla definizione di White Space[7.a]:

S (white space) consists of one or more space (#x20) characters, carriage returns, line feeds, or tabs.

I caratteri di spaziatura riconosciuti sono quindi quattro:

Altri caratteri di spaziatura, per esempio quelli così classificati in Unicode (NO-BREAK SPACE (U+00A0), WORD JOINER (U+2060), ZERO WIDTH NO-BREAK SPACE (U+FEFF), …) non sono considerati tali da XML.

Gestione delle spaziature

Contrariamente a quanto la lettura del paragrafo 2.10 White Space Handling dello standard XML potrebbe far supporre, non tutti i caratteri del documento vengono inoltrati all'applicazione: alcuni caratteri di spaziatura, in funzione del contesto o della funzione ricoperta, vengono sostituiti o rimossi.

Indicatore di fine riga

XML usa il carattere di LINE FEED come indicatore di fine riga[7.c], ed impone la sostituzione delle altre varianti esistenti presenti nel documento (CR o CR+FL) con una istanza del carattere designato. Scopo della sostituzione è semplificare il lavoro dello sviluppatore dell'applicazione XML, che ha così la certezza di avere a che fare sempre e solo un tipo di indicatore di fine riga.

Normalizzazione degli attributi

In assenza di ulteriori specifiche, XML richiede la normalizzazione dei valori degli attributi che contempla, tra le altre cose, la sostituzione di tutti i caratteri di spaziatura con uno spazio[7.e]. Se il tipo dell'attributo è specificato, e non è CDATA, allora le sequenze di spazi collassano in un unico spazio, e gli eventuali spazi presenti in testa e in coda, rimossi (trimming). In questo caso, l'effetto finale è equivalente all'applicazione della funzione XPath normalize-space.

In assenza di dichiarazione esplicita, si assume che gli attributi siano di tipo CDATA, perciò gli attributi di un documento XML privo di DTD non subiscono né collassamento nè trimming.

Spaziature ignorable

In assenza di DTD o Schema XML, tutte le spaziature del documento sono considerate significative, e di conseguenza vengono inoltrate così come sono all'applicazione — al netto degli indicatori di fine riga, tutti trasformati in LINE FEED. Se invece è disponibile una definizione della struttura del documento XML, il parser è in grado di distinguere le spaziature significative – da inoltrare all'applicazione – da quelle non significative (ignorable secondo la terminologia SAX), applicando la semplice regola[7.b]:

A validating XML processor must also inform the application which of these characters constitute white space appearing in element content.

Con element content si intende il contenuto di quegli elementi che contemplano, al loro interno, solo altri elementi, nessun testo, al più delle spaziature tra un elemento e il successivo[7.d]. Si tratta dunque delle spaziature presenti negli elementi che non prevedono contenuti #PCDATA. Riconsideriamo il frammento XML indentato, questa volta corredato di DTD:

<!DOCTYPE message [
<!ELEMENT message (#PCDATA|emphasis|list)*>
<!ELEMENT emphasis (#PCDATA)>
<!ELEMENT list (item+)>
<!ELEMENT item (#PCDATA)>
]>
<message id="42" class="confidential">Lorem ipsum
·<emphasis type="important">dolor</emphasis>
·sit amet:
··<list>
···<item>consectetur adipiscing elit;</item>

L'elemento message è una composizione di testo e nodi emphasis e list (mixed-content). Non si può quindi escludere che le spaziature presenti all'interno del nodo – evidenziate in rosso – siano state inserite dall'autore del documento per una ragione diversa dall'indentazione: non potendo fare alcuna assunzione in merito, esse devono essere inoltrate all'applicazione alla stregua di tutti gli altri caratteri.

L'elemento list, invece, non prevede del testo al suo interno, ragion per cui si può ben concludere che le spaziature in esso presenti – indicate in grigio –, per quanto tollerate (nella definizione di element content si parla di “child elements … optionally separated by white space”), non sono significative. Il parser XML in questo caso è tenuto comunque ad inoltrare le spaziature all'applicazione, ma deve in più indicarne la natura ignorable:[7.b]

A validating XML processor MUST also inform the application which of these characters constitute white space appearing in element content.

La situazione è quasi paradossale: il parser deve inviare all'applicazione anche le spaziature ignorabili. L'ambiguità che caratterizza questo aspetto di XML è almeno in parte dovuta a queste scelte terminologiche non proprio felici. Una sintesi azzeccata circa la questione delle spaziature in XML si trova in “Processing XML with Java”[2]:

One of the more obscure parts of the XML 1.0 specification is the perhaps misleadingly named «ignorable white space». This is white space that occurs between tags in places where the DTD does not allow mixed content.

L'attributo xml:space

L'attributo speciale xml:space viene usato per comunicare all'applicazione il trattamento richiesto per spaziature. L'attributo può assumere solo due valori: default e preserve. Il primo indica all'applicazione che è accettabile il trattamento predefinito delle spaziature, il secondo richiede la conservazione di tutti gli spazi.

default

Per «trattamento predefinito» si intende quello dell'applicazione, non quello dell'XML. È dunque compito dell'applicazione specificare come opera sulle spaziature nelle due modalità. Ad esempio, l'implementazione di SVG di Mozilla è piuttosto chiara, in merito:

default
The browser will remove all newline characters. Then it will convert all tab characters into space characters. Then, it will strip off all leading and trailing space characters. Then, all contiguous space characters will be consolidated.
preserve
The browser will will [sic] convert all newline and tab characters into space characters. Then, it will draw all space characters, including leading, trailing and multiple contiguous space characters. Thus, when drawn with xml:space="preserve", the string "a   b" (three spaces between "a" and "b") will produce a larger separation between "a" and "b" than "a b" (one space between "a" and "b").

Per poter usare l'attributo xml:space nell'elemento list dell'esempio, è necessario dapprima dichiararne la presenza nella DTD:

<!ELEMENT list (item+)>
<!ATTLIST list xml:space (default|preserve) 'default'>
  …
<message id="42" class="confidential">Lorem ipsum
·<emphasis type="important">dolor</emphasis>
·sit amet:
··<list xml:space="preserve">
···<item>consectetur adipiscing elit;</item>

Poiché l'effetto di xml:space si propaga automaticamente ai nodi discendenti, l'indicazione preserve dell'esempio vale anche per i discendenti di list. Va ribadito che la presenza dell'attributo non ha alcun effetto sul funzionamento del parser: è un'informazione il cui destinatario è l'applicazione, non il parser. D'altra parte, non ci si può attendere alcun effetto nemmeno da parte dell'applicazione, perché è sua facoltà recepire o ignorare le indicazioni ricevute circa la gestione delle spaziature[4]:

The xml:space attribute only matters if the software making use of the XML document recognizes it and acts upon it. This is often not the case.

Riferimenti

  1. Bray, T. “The Annotated XML Specification”. www.xml.com. <http://www.xml.com/axml/testaxml.htm>. Visitato il 12/09/2014.
  2. Harold, E. R. “Ignorable White Space”, cafeconleche.org. <http://cafeconleche.org/books/xmljava/chapters/ch06s10.html>. Visitato l'11/09/2014.
  3. Page, S. “White Space in XML Documents”. UsingXML. <http://www.usingxml.com/Basics/XmlSpace>. Visitato l'11/09/2014.
  4. Tverskov, J. “Understanding xml:space”. www.xmlplease.com. <http://www.xmlplease.com/xml/xmlspace/>. Visitato l'11/09/2014.
  5. Wang, J. “What You Need to Know About Whitespace in XML”. Oracle. <http://www.oracle.com/technetwork/articles/wang-whitespace-092897.html>. Visitato l'11/09/2014.
  6. “Canonical XML”. W3C Consortium. <http://www.w3.org/TR/xml-c14n>. Visitato l'11/09/2014.
  7. “Extensible Markup Language (XML)”. W3C Consortium:
    1. “White Space”. <http://www.w3.org/TR/REC-xml/#NT-S>;
    2. “2.10 White Space Handling”. <http://www.w3.org/TR/xml/#sec-white-space>;
    3. “2.11 End-of-Line Handling”. <http://www.w3.org/TR/xml/#sec-line-ends>;
    4. “3.2.1 Element Content”. <http://www.w3.org/TR/REC-xml/#dt-elemcontent>;
    5. “3.3.3 Attribute-Value Normalization”. <http://www.w3.org/TR/REC-xml/#AVNormalize>.
    Visitati il 12/09/2014.
  8. “White Space”. MSDN. <http://msdn.microsoft.com/en-us/library/ms256097%28v=vs.110%29.aspx>. Visitato l'11/09/2014.

Pagina modificata il 12/09/2014