<!ELEMENT nom (modèle)>
<!ELEMENT texte (paragraphe)>
<!ELEMENT paragraphe (#PCDATA)>
Un texte contient un paragraphe qui contient un flux de caractères.
<texte>
<paragraphe>Ceci est un flux de caractères</paragraphe>
</texte>
Les éléments fils déclarés peuvent être combinés pour décrire en détail la structure du contenu de l'élément en les séparant par :
,
: relation d'ordre, (x,y)
signifie " x devra être présent, et ce avant y".
|
: alternative, (x|y)
signifie "soit x soit y".
<!ELEMENT texte (titre, paragraphe)>
<!ELEMENT titre (#PCDATA)>
<!ELEMENT paragraphe (#PCDATA)>
<texte>
<titre>Ceci est le flux de caractères du titre</titre>
<paragraphe>Ceci est le flux de caractères du paragraphe</paragraphe>
</texte>
<!ELEMENT texte ((titre | accroche), paragraphe)>
<!ELEMENT titre (#PCDATA)>
<!ELEMENT accroche (#PCDATA)>
<!ELEMENT paragraphe (#PCDATA)>
Les éléments fils peuvent être déclarés avec des suffixes permettant d'exprimer leur cardinalité :
? : l'élément devra être présent de 0 à 1 fois.
* : l'élément devra être présent de 0 à n fois.
+ : l'élément devra être présent de 1 à n fois.
L'absence de suffixe indique que l'élément doit apparaître une et une seule fois.
Les éléments x, y, z1 et z2 sont représentés vides pour alléger l'exemple.
<!ELEMENT mon_elem (x?, y*, (z1, z2)+)>
permet :
<mon_elem> <x/><y/><z1/><z2/> </mon_elem>
<mon_elem> <z1/><z2/> </mon_elem>
<mon_elem> <z1/><z2/><z1/><z2/> </mon_elem>
<mon_elem> <x/><y/><y/><y/><z1/><z2/><z1/><z2/> </mon_elem>
<mon_elem> <y/><y/><y/><y/><z1/><z2/> </mon_elem>
...
L'élément racine n'est pas spécifié dans une DTD, il le sera dans la référence à la DTD faite depuis le fichier XML. Cela permet en particulier à une DTD de spécifier plusieurs langages (plusieurs éléments racines), même si cela n'est pas en général conseillé.
Par convention on déclarera en premier l'élément racine.