Linguaggi e tecnologie per il Web
Corso di Laurea in Ingegneria Informatica e Automatica
Sapienza Università di Roma
a.a. 2017/2018
XML
Parte 2:
Document Type Definition (DTD) e cenni su XML Schema
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"/>
...
I DTD sono il meccanismo "nativo" di XML per la definizione della struttura dei documenti
Essendo incentrati sui documenti sono poco adatti alla definizione di contenuti fortemente strutturati
I DTD possono essere utilizzati efficacemente per lo scambio di informazioni tra utenti, ma non tra sistemi automatici in quanto non consentono di stabilire con precisione il "tipo" delle informazioni. Storicamente i linguaggi a marcatura nascono come annotazione dei documenti testuali, ed è solo con la diffusione di XML che sono stati adoperati estensivamente per la rapresentazione delle informazioni
La specifica di un DTD non è un documento XML. Ad es.:
<!ELEMENT e (#PCDATA)>
non è una produzione XML ben formata
I meccanismi di estensione e modularizzazione dei DTD sono estremamente limitati (definizioni esterne, entità parametriche)
I DTD non sono completamente compatibili con i namespace
I DTD non permettono di stabilire vincoli di chiave ed integrità referenziale, con l'eccezione degli attributi ID ed IDREF.
XML Schema è un'applicazione XML finalizzata alla definizione
della struttura dei documenti XML, compito già svolto dai DTD, in
modo più preciso e modulare rispetto a quanto permesso da questi
ultimi.
XML Schema prevede la descrizione della struttura di un documento
con un secondo documento XML (detto schema)
Analogamente a quanto avviene con i DTD è possibile validare
un documento rispetto al proprio schema
Gli schemi XML prevedono la possibilità di creare dei modelli
dati fortemente tipati (come linguaggi di programmazione tipo C, Java o
linguaggi di specifica tipo DDL SQL) e sono compatibili con i namespace
Gli schemi XML non sono sostitutivi dei DTD, ma i due sistemi devono
essere utilizzati in concomitanza (ad es., in XML Schema non è
possibile definire le entità)
In generale per i documenti scambiati tra utenti è preferibile
utilizzare ancora i DTD, negli altri casi (ad es., strutture dati o basi
di dati) gli schemi
L'impiego degli schemi in fase di validazione è molto
più dispendioso, in termini di risorse computazionali, rispetto
ai DTD (validare solo quando necessario)
Gli schemi XML possono essere utilizzati per il data binding
XML Schema: W3C Recommendation del 2/5/2001
Definizione di un documento contenente un solo elemento di tipo
testuale.
<?xml version="1.0"?>
<E>Hello</E>
Lo schema associato è:
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="E" type="xsd:string"/>
</xsd:schema>
Il tag element
permette di definire un elemento del
documento specificandone nome e tipo.
Nella definizione di uno schema l'elemento associato alla radice del
documento (top-level element) è il primo dichiarato.
Per associare un documento (ovvero un'istanza di schema) al proprio
schema si utilizzano degli attributi associati al namespace XSI (XML
Schema Instance) sul root element, ad es:
<?xml version="1.0"?>
<E xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd">
Hello
</E>
In XML Schema si associa agli elementi un tipo (analogamente a
quanto avviene nella definizione delle strutture dati dei LdP) che
può essere semplice o complesso:
Un tipo complesso viene definito con il tag complexType
A differenza dei DTD è possibile specificare il tipo degli
elementi semplici.
All'interno dei documenti XML tali elementi sono rappresentati comunque
come stringhe, tuttavia è possibile restringere il campo delle
stringhe valide (ad es., solo quelle che rappresentano numeri in virgola
mobile, oppure numeri interi positivi, oppure date, oppure...).
I tipi semplici supportati sono:
float
, double
, decimal
,int
,byte
,unsignedInt
,postiveInt
)date
, timeInstant
,duration
,gYear
)ID
, IDREF
, ENTITY
)string
, normalizedString
)boolean
)uriReference
)<xsd:element name="NOME" type="xsd:string"/> <xsd:element name="CDL" type="xsd:string"/> <xsd:element name="DURATA" type="xsd:duration"/> <xsd:element name="INIZIO" type="xsd:date"/> <xsd:element name="ARGOMENTO" type="xsd:string"/> <xsd:element name="PROGETTO" type="xsd:string"/> <xsd:element name="CREDITI" type="xsd:nonNegativeInteger"/>
Il sistema dei tipi può essere esteso mediante un meccanismo di ereditarientà imponendo restrizioni sui tipi derivati (ad es., mediante espressioni regolari).
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="CORSO" type="TipoCorso"/>
<xsd:complexType name="TipoCorso">
<xsd:sequence>
<xsd:element name="NOME" type="xsd:string"/>
<xsd:element name="DOCENTE" type="xsd:string"/>
<xsd:element name="TUTOR" type="xsd:string"/>
<xsd:element name="CDL" type="xsd:string"/>
<xsd:element name="DURATA" type="xsd:string"/>
<xsd:element name="ARGOMENTO" type="xsd:string"/>
<xsd:element name="PROGETTO" type="xsd:string"/>
<xsd:element name="CREDITI" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Il documento è formato da un elemento associato al tag CORSO
di tipo complesso TipoCorso che contiene una sequenza di
elementi di tipo stringa. La definizione DTD "equivalente" sarebbe stata:
<!ELEMENT CORSO (NOME, DOCENTE, TUTOR, CDL, DURATA, ARGOMENTO, PROGETTO, CREDITI)>
Un'istanza del precedente schema è:
<CORSO>
<NOME>Progetto di Linguaggi e Traduttori</NOME>
<DOCENTE>Riccardo Rosati</DOCENTE>
<TUTOR>Luigi Dragone</TUTOR>
<CDL>Ing. Informatica</CDL>
...
<CORSO>
Analogamente all'impiego delle espressioni regolari per la
definizione del content model degli elementi, anche in XML Schema
è possibile stabilire le cardinalità minime e massime dei
vari elementi con l'uso degli attributi minOccurs e maxOccursche
possono assumere un qualasiasi valore numerico intero >=0
oppure
unbounded
per indicare un
numero illimitato.
Se un elemento è opzionale allora il numero minimo di
occorrenze è 0.
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="CORSO" type="TipoCorso"/>
<xsd:complexType name="TipoCorso">
<xsd:sequence>
<xsd:element name="NOME" type="xsd:string"/>
<xsd:element name="DOCENTE" type="xsd:string"/>
<xsd:element name="TUTOR" type="xsd:string"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="CDL" type="xsd:string"/>
<xsd:element name="DURATA" type="xsd:string"/>
<xsd:element name="ARGOMENTO" type="xsd:string"
minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="PROGETTO" type="xsd:string"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="CREDITI" type="xsd:string"
minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
<CORSO>
<NOME>Linguaggi e tecnologie per il Web</NOME>
<DOCENTE>Riccardo Rosati</DOCENTE>
<TUTOR>Riccardo Rosati</TUTOR>
<CDL>Ing. Informatica</CDL>
<DURATA>60 ore</DURATA>
<ARGOMENTO>Parsing</ARGOMENTO>
<ARGOMENTO>HTML</ARGOMENTO>
<ARGOMENTO>XML</ARGOMENTO>
<ARGOMENTO>Programmazione Web lato client</ARGOMENTO>
<CREDITI>6</CREDITI>
<CORSO>
Per definire elementi a contenuto testuale, ci sono due casi:
Esempio: dichiarazione di un elemento <a>
contenente un testo di tipo intero e un attributo <attr>
di tipo stringa:
<xsd:element name="a"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:integer"> <xsd:attribute name="attr" type="xsd:string" /> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element>
In XML Schema è possibile definire tipi a contenuto misto, ovvero contenenti sia parti testuali che altri elementi (e in modo più potente rispetto al mixed content model della DTD).
Esempio di dichiarazione di elemento <a>
contenente sia parti testuali l'elemento <b>
:
<xsd:element name="a"> <xsd:complexType mixed="true"> <xsd:element name="b" type="tipo1"/> </xsd:complexType> </xsd:element>
Esempio di dichiarazione di elemento <a>
contenente sia parti testuali che gli elementi <b>
, <c>
, <d>
:
<xsd:element name="a"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="b" type="tipo1"/> <xsd:element name="c" type="tipo2"/> <xsd:element name="d" type="tipo1"/> </xsd:sequence> </xsd:complexType> </xsd:element>
In XML Schema è possibile dichiarare elementi a contenuto vuoto (analogamente al content model EMPTY
della DTD).
<a>
vuoto (e senza attributi):
<xsd:element name="a"> <xsd:complexType/> </xsd:element>Esempio di dichiarazione di un elemento
<a>
vuoto con un attributo attr
di tipo intero positivo:
<xsd:element name="a"> <xsd:complexType> <xsd:attribute name="attr" type="xsd:positiveInteger"/> </xsd:complexType> </xsd:element>
Un elemento incluso in un tipo complesso può essere a sua
volta associato ad un tipo complesso.
In tal modo i tipi possono essere composti, inoltre le definizione
di un tipo può essere condivisa tra più elementi (anche se
appartenenti a tipi diversi).
Una funzionalità di questo tipo può essere ottenuta
con i DTD mediante l'impiego delle entità parametriche, ma
risulta di difficile applicabilità.
Ad esempio il docente e gli eventuali tutori possono avere un nominativo ed un recapito.
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="CORSO" type="TipoCorso"/>
<xsd:complexType name="TipoPersona">
<xsd:sequence>
<xsd:element name="NOMINATIVO" type="xsd:string"/>
<xsd:element name="RECAPITO" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="TipoCorso">
<xsd:sequence>
<xsd:element name="NOME" type="xsd:string"/>
<xsd:element name="DOCENTE" type="TipoPersona"/>
<xsd:element name="TUTOR" type="TipoPersona"
minOccurs="0" maxOccurs="unbounded"/>
...
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
<CORSO>
...
<TUTOR>
<NOMINATIVO>Luigi Dragone</NOMINATIVO>
<RECAPITO>dragone@dis.uniroma1.it</RECAPITO>
</TUTOR>
...
</CORSO>
Il tipo di un elemento può essere dichiarato all'interno
all'elemento stesso (anonymous type), in tale caso la definizione non
può essere condivisa.
Si tratta di un caso analogo all'uso delle classi anonime in Java.
Ad esempio, il nominativo è suddiviso in nome e cognome:
<xsd:complexType name="TipoPersona">
<xsd:sequence>
<xsd:element name="NOMINATIVO">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="NOME" type="xsd:string"/>
<xsd:element name="COGNOME" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="RECAPITO" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<CORSO>
...
<TUTOR>
<NOMINATIVO><NOME>Luigi</NOME><COGNOME>Dragone</COGNOME></NOMINATIVO>
<RECAPITO>dragone@dis.uniroma1.it</RECAPITO>
</TUTOR>
...
</CORSO>
Il raggruppamento degli elementi all'interno della definizione di un
tipo può avvenire in 3 modalità
sequence
), equivalente
all'operatore ,
delle espressioni dei content model all
), simile
all'operatore ?
delle espressioni dei content model SGML,
ma non XMLchoice
), equivalente
all'operatore |
delle espressioni dei content modelL'impiego dell'elemento all
permette di specificare
la presenza di un insieme di elementi indipendentemente dall'ordine. Gli
elementi devono essere specificati con cardinalità massime e
minime ristrette ai soli valori 0 ed 1.
Ad esempio, nel nominativo di una persona non è rilevante l'ordine del nome e del cognome:
<xsd:complexType name="TipoNominativo">
<xsd:all>
<xsd:element name="NOME" type="xsd:string"
minOccurs="1" maxOccurs="1"/>
<xsd:element name="COGNOME" type="xsd:string"
minOccurs="1" maxOccurs="1"/>
</xsd:all>
</xsd:complexType>
<CORSO>
...
<TUTOR>
<NOMINATIVO><COGNOME>Dragone</COGNOME><NOME>Luigi</NOME></NOMINATIVO>
<RECAPITO>dragone@dis.uniroma1.it</RECAPITO>
</TUTOR>
...
</CORSO>
Le scelte alternative possono essere combinate con le sequenze, analogamente a quanto avviene nei content model dei DTD, e specificare un intervallo di cardinalità ammissibili (ripetizioni).
<xsd:complexType name="TipoOrario">
<xsd:sequence>
<xsd:element name="DURATA" type="xsd:string"/>
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element name="LEZIONE" type="TipoLezione"/>
<xsd:element name="ESERCITAZIONE" type="TipoEsercitazione"/>
<xsd:element name="SEMINARIO" type="TipoSeminario"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
Nel caso in cui lo stesso elemento può comparire all'interno di più elementi, è possibile usare l'attributo ref
di <xsd:element>
. Usando tale attributo al posto dell'attributo name
, si fa riferimento alla dichiarazione dell'elemento il cui nome è il valore dell'attributo ref
.
Ad esempio, il seguente frammento di schema stabilisce che l'elemento <a>
compare nel content model degli elementi <b>, <c>, <d>
, senza ripetere più volte la dichiarazione dell'elemento <a>
:
<xsd:element name="a"> <xsd:complexType> ... </xsd:complexType> </xsd:element> <xsd:element name="b"> <xsd:complexType> <xsd:element ref="a"> </xsd:complexType> </xsd:element> <xsd:element name="c"> <xsd:complexType> <xsd:element ref="a"> </xsd:complexType> </xsd:element> <xsd:element name="d"> <xsd:complexType> <xsd:element ref="a"> </xsd:complexType> </xsd:element>
La definizione dei tipi complessi ammette la possibilità di specificare i relativi attributi. Analogamente agli elementi anche gli attributi sono fortemente tipati ed è possibile specificare l'obbligatorietà oppure il valore predefinito.
<xsd:complexType name="TipoCorso">Possono essere definiti anche gruppi di attributi condivisi da più tipi/elementi.
<xsd:sequence>
<xsd:element name="NOME" type="xsd:string"/>
...
</xsd:sequence>
<xsd:attribute name="codice" type="xsd:string" use="required"/>
<xsd:attribute name="homePage" type="xsd:uriReference"/>
</xsd:complexType>
A differenza dei DTD, gli schemi sono compatibili con i namespace.
L'elemento schema possiede un attributo (targetNamespace) che
specifica l'URI del namespace associato agli elementi in corso di
definizione. Si deve specificare che gli elementi appartengono a tale
namespace, mentre gli attributi in genere non sono associati a nessun
namespace.
<?xml version="1.0"?>
<xsd:schema
xmlns="urn:dis.uniroma1.it:corso"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsd:targetNamespace="urn:dis.uniroma1.it:corso"
xsd:elementFormDefault="qualified"
xsd:attributeFormDefault="unqualified">
<xsd:element name="CORSO" type="TipoCorso"/>
...
</xsd:schema>
L'impiego dei namespace richiede l'uso di un diverso costrutto per
referenziare lo schema
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<corso:CORSO xmlns:corso="urn:dis.uniroma1.it:corso"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:dis.uniroma1.it:corso http://www.dis.uniroma.it/schema/corso.xsd">
...
</corso:CORSO>
L'URI del namespace è indipendente da quella dello schema.
Mentre la prima non deve essere mai risolta (ovvero convertita in un
indirizzo reale), la seconda deve puntare ad un'istanza del documento
contentente lo schema. Si può associare anche ad uno schema
un'indirizzo "virtuale" mediante un'URN, in tale caso il parser deve
possedere una copia interna dello schema in questione, analogamente a
quanto fatto dagli attuali browser web per il DTD di HTML.
Nota: per i costrutti avanzati di XML Schema e per ulteriori dettagli si rimanda ai documenti ufficiali W3C (vedi riferimenti seguenti).
Extensible Markup Language (XML) 1.0 (Fifth Edition) W3C Recommendation
XML Schema Part 0: Primer W3C Recommendation October 28, 2004
XML Schema Part 1:
Structures W3C Recommendation October 28, 2004
XML Schema Part 2:
Datatypes W3C Recommendation October 28, 2004