# Document Type Definition

Il Document Type Definition (lett. 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:
definisce una struttura così composta:

## 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:
DTD esterno:

### Elemento di DTD

Ciascun elemento deve essere dichiarato in una DTD con dichiarazioni di tipo di elemento. Tali dichiarazioni hanno la forma:
Esempio:

#### #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

Esempio:

#### 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.

##### Esempio
### Elementi annidati

Gli elementi possono essere contenitori per altri elementi (elementi annidati).
L'elemento radice di un documento XML normalmente è di questo tipo. Esempio:
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:

### Attributo

Le dichiarazioni di attributo hanno la forma seguente:
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:
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
#### 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:

### Indicatori di occorrenza

Nella DTD vengono utilizzati dei simboli che predispongono il parsing a contare le occorrenze di un oggetto.
* , (es. a, b, c) 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ù).