Linguaggi e tecnologie per il Web
Corso di Laurea in Ingegneria Informatica e Automatica
Sapienza Università di Roma
a.a. 2015/2016
XML
Parte 2:
Document Type Definition (DTD) e analisi sintattica di XML
Luigi Dragone, Riccardo Rosati
Un documento XML è costituito da:
Un documento XML ben formato può avere una struttura arbitraria:
Sono utili, ma poco più utili di testo non strutturato.
Serve un meccanismo per imporre struttura ad un documento:
Un DTD specifica quali sono le strutture ammesse per l'istanza di documento:
L'insieme di tipi di elemento in un DTD viene detto vocabolario.
In XML tutte le dichiarazioni hanno la forma:
<!OGGETTO-DICHIARATO ... >
Esempi:
<!DOCTYPE ...
>
<!ELEMENT ... >
<!ATTLIST ... >
<!ENTITY ... >
<!NOTATION ... >
Un documento XML può contenere una DTD.
La DTD deve precedere il primo elemento (l'elemento radice).
Le dichiarazioni nella DTD possono essere:
<!DOCTYPE esempio SYSTEM "esempio.dtd">
Un documento XML viene detto valido se:
Osservazione: lo spazio bianco non è rilevante (di norma)
Sintassi di una dichiarazione di tipo di elemento:
<!ELEMENT nome-elemento content-model>
Il content model specifica la struttura degli elementi di nome nome-elemento.
content model è un'espressione regolare costruita su:
Ci sono delle limitazioni nell'uso di #PCDATA nel content model che vedremo più avanti.
Operatori usati nel content model sono quelli delle espressioni regolari:
Un'istanza di documento è conforme ad un DTD se può essere generata a partire dal tipo di elemento iniziale applicando le produzioni (ovvero le dichiarazioni di tipo di elemento) del DTD.
Le ECFG sono estensioni delle CFG:
Per derivare (generare) una frase del linguaggio:
Un dichiarazione di tipo di elemento corrisponde ad una produzione di una ECFG:
Il tipo di documento specificato nella DTD corrisponde al simbolo iniziale della grammatica.
Da un punto di vista astratto una DTD è una ECFG.
La DTD (vista come grammatica) genera l'insieme di documenti validi.
Importante differenza tra ECFG e DTD:
Le etichette nel documento "dicono" quali produzioni sono state applicate.
Motivazione: analizzatori sintattici semplici ed efficienti
DTD:
S => <S>
AB+
</S> => <S>
AB </S>
=>
<S> <A> a </A> B </S>
=>
<S> <A> a </A> <B>b </B></S>
ECFG:
S -> AB+
A -> a
B -> b
S => AB+ => AB => aB => ab
ECFG con marcature:
S -> <S>AB+</S>
A -> <A>#PCDATA</A>
B -> <B>#PCDATA</B>
Una conseguenza importante del fatto che ogni istanza di documento conforme ad un DTD contiene le etichette derivanti dall'applicazione delle produzioni, è che il linguaggio (comprese le etichette) generato da un DTD è un linguaggio LL(1).
L'annidamento degli elementi definisce in modo esplicito una
struttura ad albero:
<Mail>
<From> <Address> Dante@dsn.fi.it </Address>
</From>
<To> <Address> Beatrice@pitti.fi.it </Address>
<Address>
Virgilio@spqr.rm.it </Address>
</To>
<Subject> Appointment </Subject>
<Body> Why don't we meet at disco.inferno at
midnight. Tell also
Caronte. Cheers,
- D.A.
</Body>
</Mail>
Ad ogni documento XML corrisponde una struttura ad albero:
Definito in modo standard dal Document Object Model
Negli esempi che seguono:
<!DOCTYPE ESE SYSTEM "esempio.dtd"> (che fa riferimento al file esterno esempio.dtd)
<!ELEMENT ESE (#PCDATA)>
Il tipo dell'elemento radice deve essere il tipo di documento.
<ESE>questo documento e`
valido</ESE>
Documenti non validi:
<boh>questo documento NON e`
valido</boh>
<ese>XML e` case sensitive</ese>
<!ELEMENT ESE (#PCDATA)>
A #PCDATA deve corrispondere solo testo senza elementi annidati. Il testo può anche essere vuoto
<ESE>questi documenti sono
validi</ESE>
<ESE></ESE>
<ESE/>
Documento non valido:
<ESE>questo documento
<b>NON</b> e` valido</ESE>
Elemento che contiene una sequenza fissata di altri elementi.
<ESE> <P1>questa e` la
prima parte</P1>
<P2>questa e` la
seconda parte</P2> </ESE>
<ESE> <P1/> <P2>la prima parte e`
vuota</P2> </ESE>
Documenti non validi:
<ESE> <P1>manca
P2</P1> ____ </ESE>
<ESE> <P2/> <P1>ordine sbagliato</P1>
</ESE>
<ESE> <P1/> <P2/> <P2>un solo
P2</P2> </ESE>
<ESE> NO testo libero <P1/> <P2/> </ESE>
Elemento che occorre zero o più volte.
<ESE> <IN>intro</IN>
<S>sez1</S> <S>sez2</S> </ESE>
<ESE> <IN>senza sezioni</IN> </ESE>
Documenti non validi:
<ESE>
<S>intro ci deve essere</S> </ESE>
<ESE> <S>solo dopo intro</S> <IN/>
<S>sez1</S> </ESE>
<!ELEMENT ESE (IN, S+)>
<!ELEMENT IN (#PCDATA)>
<!ELEMENT S (#PCDATA)>
Elemento che occorre una o più volte.
<ESE> <IN>intro</IN>
<S>sezione unica</S> </ESE>
<ESE> <IN>intro</IN> <S>sez1</S>
<S>sez2</S> </ESE>
Documenti non validi:
<ESE> <IN>almeno una
sezione</IN> _____ </ESE>
<ESE> _____ <S>intro ci deve
essere</S> </ESE>
<ESE> <S>solo dopo intro</S> </IN>
<S>sez1</S> </ESE>
<!ELEMENT ESE (IN?, S+)>
<!ELEMENT IN (#PCDATA)>
<!ELEMENT S (#PCDATA)>
Elemento opzionale.
<ESE> <IN>intro</IN>
<S>sez1</S> <S>sez2</S> </ESE>
<ESE> <S>senza introduzione</S> </ESE>
Documenti non validi:
<ESE> <IN>intro</IN>
<IN>intro unica</IN> <S/> </ESE>
<ESE> <IN>almeno una
sezione</IN> _____ </ESE>
<ESE> <S>solo dopo intro</S> </IN>
<S>sez1</S> </ESE>
<!ELEMENT ESE (IN?, (A1 | A2))>
<!ELEMENT IN (#PCDATA)>
<!ELEMENT A1 (#PCDATA)>
<!ELEMENT A2 (#PCDATA)>
Una tra più alternative.
<ESE> <IN>intro</IN>
<A1>alternativa 1</A1> </ESE>
<ESE> <IN>intro</IN> <A2>alternativa
2</A2> </ESE>
<ESE> <A1>senza introduzione</A1> </ESE>
Documenti non validi:
<ESE> <IN>serve una delle
2</IN> _____ </ESE>
<ESE> <IN/> <A1>al piu` una delle 2</A1>
<A2/> </ESE>
<ESE> <IN/> <A1>qui solo testo <A2/>
</A1> </ESE>
Elementi annidati a un numero fisso di livelli.
<ESE> <TI>esempi
xml</TI>
<S1> <TI>sez
1</TI>
<S2>sez 1.1</S2>
</S1>
<S1> <TI>sez 2
ha solo titolo<TI> </S1>
<S1> <S2/>
</S1>
<S1/>
</ESE>
<!ELEMENT ESE (TI, S1+)>
<!ELEMENT TI (#PCDATA)>
<!ELEMENT S1 (TI?, S2*)>
<!ELEMENT S2 (#PCDATA)>
Documenti non validi:
<ESE> <TI>manca sez. liv.
1</TI> _____ </ESE>
<ESE> _____
<S1> niente testo
direttamente in S1
<S2>sezione 1.1</S2>
<S2>sezione 1.2</S2>
<S2> <TI>solo testo in S2</TI> </S2>
</S1>
</ESE>
Elementi annidati a livelli arbitrari.
<ESE> <TI>esempi
xml</TI>
<S> <TI>tit
sez.1</TI> <TXT>testo 1</TXT> </S>
<S> <TI>tit
sez.2</TI>
<S> <TXT>testo sez.2.1</TXT> </S>
<S> <TI>titolo sez.2.2</TI>
<S> <TXT>testo sez.2.2.1</TXT> </S>
</S>
</S>
</ESE>
<!ELEMENT ESE (TI, S+)>
<!ELEMENT S (#PCDATA | COM | S)*>
<!ELEMENT TI (#PCDATA)>
<!ELEMENT COM (#PCDATA)>
Un elemento può contenere testo misto ad altri elementi
(elemento a contenuto misto).
<ESE> <TI>esempi
xml</TI> <S>sezione 1</S>
<S> sezione 2 <S>sezione
2.1</S>
<COM>commento in
sez. 2</COM>
altro testo di sezione
2
<S> sezione 2.2
<S>sezione 2.2.1</S>
<COM>sez. 2.2.2 vuota</COM> <S/> </S>
</S>
</ESE>
#PCDATA ed altri elementi non possono essere combinati in modo arbitrario nel content model.
L'unica possibilità di combinarli è:
<!ELEMENT elem (#PCDATA | elem1 | ... | elemk)*>
Un elemento di questo tipo viene detto a contenuto misto:
Un content model che contiene #PCDATA ed altri elementi e
non ha la forma vista prima è scorretto.
<!ELEMENT ESE (TI, #PCDATA)>
<!ELEMENT ESE (TI?, #PCDATA)>
<!ELEMENT ESE (TI, (#PCDATA | S*))>
<!ELEMENT ESE (TI, (#PCDATA | S)*)>
<!ELEMENT S (#PCDATA | COM | S)+>
<!ELEMENT COM (#PCDATA)+>
Un elemento può essere forzato ad avere contenuto vuoto:
<!ELEMENT elem EMPTY>
Un elemento dichiarato EMPTY può comparire solo con
l'etichetta di elemento vuoto.
<!ELEMENT VUOTO EMPTY>
<!ELEMENT E1 (#PCDATA)>
Corretto:
<E1></E1> <E1/> <VUOTO/>
Scorretto:
<VUOTO> deve essere vuoto
</VUOTO>
<VUOTO></VUOTO>
Non sono inutili in quanto aggiungono informazione al documento:
<BR/> di HTML
Si può usare il contenuto ANY per specificare che il contenuto di un elemento è una sequenza di testo ed elementi qualsiasi:
<!ELEMENT elem ANY>
Tutti gli elementi che compaiono in un elemento con contenuto ANY devono essere stati dichiarati.
<!ELEMENT TUTTO ANY>
<!ELEMENT E1 (#PCDATA)>
<!ELEMENT E2 (#PCDATA)>
Corretto:
<TUTTO> <E1>xxx</E1> yyy <E2/> <E1/> </TUTTO>
Scorretto:
<TUTTO> <E3>non dichiarato</E3> </TUTTO>
Un documento XML:
Un'entità è un'unità di memorizzazione contenente una parte di un documento XML:
La nozione di Uniform Resource Identifier (URI) generalizza quella di Uniform Resource Locator (URL), separando la risorsa dalla sua locazione.
Riferimento ad un'entità nel documento: &nome-entita;
Dichiarazioni nel DTD:
<!ENTITY
DIS "Dip. di Informatica e Sist.">
<!ENTITY SEZIONE1 SYSTEM "sezione1.xml">
<!ENTITY SEZIONE2 "<Sezione>Da
scrivere.</Sezione>">
Riferimenti nell'istanza di documento:
Presso il &DIS; vengono studiati i
linguaggi
per dati semistrutturati, come illustrato nelle
due sezioni seguenti.
&SEZIONE1;
&SEZIONE2;
Un processore XML sostituisce tutti i riferimenti alle entità parsable con il loro valore prima di passare il documento all'applicazione.
Sono entità che si possono usare nel DTD (non nell'internal DTD subset).
<!ENTITY % Text "CDATA">
<!ENTITY % coreattrs
"id
ID
#IMPLIED
class
CDATA #IMPLIED
title
%Text; #IMPLIED
..." >
Riferimento ad un'entità parametro: %nome-entita;
È permesso solo nel DTD.
Uso di un DTD esterno
<!ENTITY % formule SYSTEM
"http://.../formule.dtd">
%formule
Un elemento può contenere degli attributi nell'etichetta iniziale.
Se il documento è valido tutti gli attributi devono essere stati dichiarati.
Sintassi di una dichiarazione di attributi per un elemento:
<!ATTLIST nome-elemento lista-attributi>
XML distingue 10 possibili tipi di attributo:
Il valore-di-default può essere
Elemento img di XHTML:
<!ELEMENT img EMPTY>
<!ATTLIST img
id
ID
#IMPLIED
class
CDATA #IMPLIED
title
CDATA #IMPLIED
src
CDATA #REQUIRED
alt
CDATA #REQUIRED
longdesc
CDATA #IMPLIED
height
CDATA #IMPLIED
width
CDATA #IMPLIED
usemap
CDATA #IMPLIED
ismap
(ismap) #IMPLIED
...
>
Permettono di riferirsi a dati esterni in forma binaria.
Il valore di un attributo di tipo ENTITY è il nome
di un'entità esterna dichiarata nel DTD.
<!ELEMENT IMAGE EMPTY>
<!ATTLIST IMAGE SOURCE ENTITY #REQUIRED>
<!ENTITY LOGO SYSTEM "logo.gif">
Nel documento posso inserire un riferimento all'immagine:
...
<IMAGE SOURCE="LOGO"/>
...
Extensible Markup Language (XML) 1.0 (Fifth Edition) W3C Recommendation