Document Type Definition

Il Document Type Definition ( definizione del tipo di documenti, noto anche con l'acronimo DTD) è un insieme di regole che definisce le componenti ammesse nella costruzione di un documento SGML (XML, HTML o XHTML) utilizzando una grammatica espressa in EBNF.

In SGML un DTD è necessario per la validazione del documento. Anche in XML un documento è valido se presenta un DTD ed è possibile validarlo usando il DTD.

Tuttavia XML permette anche documenti ben formati, ovvero documenti che, pur essendo privi di DTD, presentano una struttura sufficientemente regolare e comprensibile da poter essere controllata.

Il DTD si può dichiarare all'interno di uno stesso documento XML (dichiarazione inline).

Cosa fa un DTD 
 Definisce gli elementi leciti all'interno del documento. Non si possono usare altri elementi se non quelli definiti. Una specie di "vocabolario" per i file che lo useranno.
 Definisce la struttura di ogni elemento. La struttura indica cosa può contenere ciascun elemento, l'ordine, la quantità di elementi che possono comparire e se sono opzionali o obbligatori. Una specie di "grammatica".
 Dichiara una serie di attributi per ogni elemento e che valori possono o devono assumere questi attributi.
 Fornisce infine alcuni meccanismi per semplificare la gestione del documento, come la possibilità di dichiarare entity e la possibilità di importare parti di altri DTD.

Inoltre il DTD serve ad un parser per controllare la correttezza di un documento (well formed).

Esempio 
Il seguente DTD:
<!ELEMENT persona (nome, cognome)>
<!ELEMENT nome (#PCDATA)>
<!ELEMENT cognome (#PCDATA)>

definisce una struttura così composta:

<persona>
  <nome>Mario</nome>
  <cognome>Rossi</cognome>
</persona>

Sintassi DTD 
Un DTD è opzionale e può essere specificato all'inizio di un documento XML, inoltre può essere specificato se le definizioni sono interne od esterne al documento XML.

DTD interno:
<!DOCTYPE Report [ ...
]>

DTD esterno:
<!DOCTYPE Report SYSTEM “Report.dtd”>
<!DOCTYPE Report PUBLIC “Report.dtd”>

Elemento di DTD 
Ciascun elemento deve essere dichiarato in una DTD con dichiarazioni di tipo di elemento. Tali dichiarazioni hanno la forma:
<!ELEMENT nome-elemento ( modello di contenuto )>

Esempio:
<?xml version = "1.0"?>
<!DOCTYPE nota [
<!ELEMENT nota (#PCDATA)>
]>
<nota>Ricordati di acquistare il latte tornando a casa</nota>

#PCDATA 
 PCDATA è una parola chiave riservata alla DTD per "Parsed Character Data", che indica del testo generico.
 PCDATA indica che l'elemento contiene dati di testo leggibili da un analizzatore XML ed elaborati opportunamente. Se ci sono marcatori nei PCDATA, possono influenzare l'analisi sintattica del documento.

Parola chiave ANY 
Si può definire un certo elemento sapendolo certamente non vuoto (cioè contiene elementi o testo o entrambi), ma senza conoscere
esattamente il modello di contenuto. Nella DTD si può usare allora la parola chiave ANY per dichiarare che il contenuto di quell'elemento può essere qualsiasi cosa.

Sintassi
<!ELEMENT nome ANY>

Esempio:
<?xml version = "1.0"?>
<!DOCTYPE nota[
<!ELEMENT nota ANY>
<!ELEMENT numero EMPTY>
<!ELEMENT messaggio (#PCDATA)>
<!ELEMENT data EMPTY>
]>
<nota>
<numero />
<messaggio> Ricordati di comprare il latte tornando a casa</messaggio>
<data />
</nota>

Contenuto misto dell'elemento 
Se si vuole definire una regola che consenta a un elemento di contenere testo o altri elementi in qualche combinazione si usa un modello a contenuto misto. 

Sintassi
<!ELEMENT nome (#PCDATA | figlio)*>

Esempio
<?xml version = "1.0"?>
<!DOCTYPE nota[
<!ELEMENT nota (#PCDATA | numero | messaggio | data )*>
<!ELEMENT numero EMPTY>
<!ELEMENT messaggio ( #PCDATA )>
<!ELEMENT data EMPTY>
]>
<nota>Nota importante
<numero />
<messaggio>Ricordati di comprare il latte tornando a casa</messaggio>
<data />
</nota>

Elementi annidati 
Gli elementi possono essere contenitori per altri elementi (elementi annidati).

L'elemento radice di un documento XML normalmente è di questo tipo. Esempio:
<?xml version = "1.0"?>
<!DOCTYPE nota [
<!ELEMENT nota ( messaggio )>
<!ELEMENT messaggio ( #PCDATA)>
]>
<nota>
<messaggio> Ricordati di comprare il latte tornando a
casa</messaggio>
</nota>

La definizione DTD prevede dapprima la dichiarazione dell'elemento radice e tra parentesi tonde l'elenco degli elementi annidati, e dopo la dichiarazione per ogni elemento annidato.

Elemento vuoto 

Gli elementi vuoti normalmente vengono usati come
segnaposto, o per fornire valori di attributi necessari che non
modificano propriamente altri elementi. La parola chiave EMPTY nel modello di contenuto di un elemento dichiara che è un elemento vuoto. Esempio:
<?xml version = "1.0"?>
<!DOCTYPE nota [
<!ELEMENT nota (numero, messaggio)>
<!ELEMENT numero EMPTY>
<!ELEMENT messaggio(#PCDATA)>
]>
<nota>
<numero />
<messaggio> Ricordati di comprare il latte tornando a casa</messaggio>
</nota>

Attributo 
Le dichiarazioni di attributo hanno la forma seguente:
<!ATTLIST nome-elemento
nome-attributo1 (tipo) valori_predefiniti
nome-attributo2 (tipo) valori_predefiniti>

In una DTD si dichiarano tre tipi fondamentali di attributi:
 Stringhe, indicate dalla parola chiave CDATA (CDATA è solo testo, ma testo che l'analizzatore sintattico non tenta di elaborare; i caratteri di marcatura, come le parentesi angolari, vengono ignorati nei segmenti CDATA, ma risolti nei segmenti PCDATA.)
 Attributi tokenizzati, indicati da token dichiarati
 Attributi enumerati, per i quali viene indicata una serie di valori validi fra cui scegliere

Valori predefiniti degli attributi 
 #REQUIRED Specifica che l'attributo è obbligatorio
 #FIXED Fornisce una dichiarazione di costante per il valore di un attributo. Se il valore è diverso da quello dichiarato, il documento non è valido
 #IMPLIED L'attributo è facoltativo. Cioè, se l'attributo non appare nell'elemento, l'applicazione di elaborazione può usare qualsiasi valore (se necessario).

Esempio:
<?xml version = "1.0"?>
<!DOCTYPE nota [
<!ELEMENT nota (messaggio)>
<!ELEMENT messaggio (#PCDATA)>
<!ATTLIST messaggio
numero CDATA #REQUIRED
data CDATA #REQUIRED>]>
<nota>
<messaggio numero="10" data="140305">
Ricordati di comprare il latte tornando a casa
</messaggio>
</nota>

La parola chiave CDATA consente l'inclusione nella stringa di qualsiasi carattere, fuorché ,  e .

Attributi tokenizzati 
Le opzioni tokenizzate danno il modo per limitare i valori permessi per gli attributi. Per esempio, possiamo volere che ciascun elemento abbia un identificativo unico, oppure permettere che un attributo possa avere solo uno o due valori diversi.

Tipi di attributi tokenizzati nelle DTD:
 ID Identifica in modo univoco un elemento
 IDREF Punta ad un elemento che ha un attributo ID 
 IDREFS Punta a più elementi che hanno un attributo ID. Gli attributi puntati sono elencati separati da uno spazio
 ENTITIES Fa riferimento a una entità esterna non analizzata sintatticamente
 NMTOKEN definisce qualche limitazione ai caratteri accettabili nei contenuti XML;
in particolare, limita i dati alle stesse regole usate nelle convenzioni sui nomi di elemento XML Il tipo di attributo name token, cioè NMTOKEN, restringe i valori validi a quelli costituiti da lettere, cifre, punti, trattini, virgole e sottolineature.

Esempio
<?xml version = "1.0"?>
<!DOCTYPE nota [
<!ELEMENT nota ( messaggio+, risultato+)>
<!ELEMENT messaggio (#PCDATA)>
<!ATTLIST messaggio
numero ID #REQUIRED
da CDATA #REQUIRED>
<!ELEMENT risultato (#PCDATA)>
<!ATTLIST risultato
msg IDREF #IMPLIED>
]>
<nota>
<messaggio numero="a1" da="Pippo">Ricordati di comprare il latte tornando a
casa</messaggio>
<messaggio numero="a2" da="Pluto">Ho bisogno di aiuto per i compiti a casa
</messaggio>
<risultato msg="a1">il latte era scaduto</risultato>
<risultato msg="a1">sono andato in un altro negozio</risultato>
<risultato msg="a2">ho finito presto i compiti</risultato>
</nota>

Attributi enumerati 
Gli attributi di tipo enumerato descrivono un elenco di valori possibili per l'attributo valutato. Perché sia soddisfatto il requisito della validità, l'attributo deve avere uno dei valori presenti nell'elenco; in ogni altro caso viene considerato non valido. I valori enumerati sono separati da un carattere "pipe" (|), che è interpretato come "or" logico dal processore XML.

Esempio:
<!ATTLIST messaggio
Avviso ( basso | normale | urgente) “basso”>

Indicatori di occorrenza 
Nella DTD vengono utilizzati dei simboli che predispongono il parsing a contare le occorrenze di un oggetto. 
  (es. ) Questo operatore di sequenza separa i membri di una lista che richiede l'uso sequenziale di tutti i membri della lista (a seguito da b, seguito da c)
 | (es. a|b|c) Questo è un operatore di scelta, che separa membri di una lista quando è richiesto l'uso di uno e uno solo dei membri (a o b o c).

La mancanza di un simbolo indica una occorrenza necessaria (uno e uno solo di dati). 
  designa una occorrenza facoltativa (zero o uno).
  indica un'occorrenza obbligatoria e ripetibile (uno o più).
  indica un'occorrenza facoltativa e ripetibile (zero, uno o più).

Note

Bibliografia

Voci correlate 
 XML Schema

Collegamenti esterni 
 

Standard informatici basati su XML
Standard Internet