L'objectif d'une DTD est de pouvoir définir un modèle de données formel, sous forme électronique, afin que les outils puissent valider, de façon automatisée, la conformité d'une classe de documents XML à ce modèle.
Une DTD définit tout ce qui est nécessaire comme ressources à tous les documents d'une classe donnée. Si un document XML doit inclure des fragments externes, ceux-ci seront définis et identifiés de façon formelle au sein de la DTD, afin de pouvoir ensuite être appelés au sein des documents.
Une DTD permet de définir une organisation d'éléments entre eux et des typages de ces éléments via des notions d'attribut (de valuation).
Plus précisément, une DTD définit un modèle d'organisation hiérarchique de documents XML en utilisant :
La syntaxe utilisée pour écrire des DTD est une syntaxe ad hoc. Par exemple, déclarer un élément article contenant un en-tête et un corps s'écrira :
<!ELEMENT article (en-tete, corps) >
Cette syntaxe est concise et simple, mais présente le grand désavantage de ne pas être celle utilisée pour écrire des documents XML et, donc, de ne pas pouvoir être analysée par des outils XML standard. C'est une des raisons qui amène à la définition des modèles Schema.
<!ENTITY nbsp " ">
<!ENTITY iexcl "¡">
fichier de DTD :
<!ENTITY DDT "Dichlorodiphenyltrichloréthane">fichier XML :
Le &DDT; est un pesticide qui a abondamment polué la chaîne alimentaire ...résultat pour l'application traitant le document (par ex. un navigateur):
Le Dichlorodiphenyltrichloréthane est un pesticide qui a abondamment polué la chaîne alimentaire ...
<!ENTITY Inclusion SYSTEM "FichierContenantDuXml.xml">
fichier XML utilisant l'entité (le contenu de FichierContenantDuXml.xml y sera inséré) :
<balise>... &Inclusion; ...</balise>
référence à la DTD externe :
<!ENTITY % Inclusion SYSTEM "FichierContenantLaDTD.dtd">importation du contenu de la DTD externe dans la DTD courante :
%Inclusion;
Ce mécanisme d'inclusion est extrêmement utile pour toutes les opérations de modularisation et de réutilisation.
Note: il n'y a pas de concept d'espace de noms pour les DTDs. Quand on importe une DTD externe dans la DTD courante, les symboles définis dans la DTD externe deviennent accessibles de la même façon que les symboles définis de manière interne. Il y a donc risque de collision de noms si la DTD externe emploie un ou plusieurs symboles identiques à ceux de la DTD courante.
<!ENTITY % heading "H1|H2|H3|H4|H5|H6">
<!ENTITY % list "UL | OL">
<!ENTITY % preformatted "PRE">
<!ENTITY % block
"P | %heading; | %list; | %preformatted; | DL | DIV | NOSCRIPT | BLOCKQUOTE
| FORM | HR | TABLE | FIELDSET | ADDRESS">
l'entité %block; sera définie comme "P | H1 | H2 | H3 | H4 | H5 | H6 | UL | OL | PRE | DL | DIV | NOSCRIPT | BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS"
<!ELEMENT UL (LI)+>
<!ELEMENT IMG EMPTY>
<!ELEMENT BR EMPTY>
Nom de la balise | type de contenu entre balise de début et de fin | ||
<!ELEMENT | UL | (LI)+ | > |
<!ELEMENT | IMG | EMPTY | > |
<!ELEMENT | BR | EMPTY | > |
( ) | les parenthèses n'ont pas de signification en elles-mêmes. Elles servent à regrouper, par exemple pour faire porter l'effet d'un signe sur l'ensemble du contenu des parenthèses, par exemple (LI)+, ou pour énumérer une série d'alternatives, par exemple (H1 | H2 | H3 | H4 | H5 | H6). |
---|---|
Nom | la présence d'un nom d'élément indique que cet élément doit se trouver entre la balise de début et la balise de fin de l'élément courant |
+ | Ce qui précède doit être présent une ou plusieurs fois. Par exemple, (LI)+ signifie que l'élément LI doit être présent au moins une fois et peut être présent plusieurs fois dans un élément UL. |
? | Ce qui précède doit être présent au plus une fois. Par exemple
<!ELEMENT table (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> indique que l'élément caption peut être présent au plus une fois dans l'élément table |
* | Ce qui précède peut être présent zéro, une ou plusieurs fois |
-(...) | Ce qui est entre parenthèses ne doit pas être présent.
Par exemple <!ELEMENT A (%inline;)* -(A)> indique que l'élément A (pour ancrer une référence hypertexte) peut contenir ce qui est défini par l'entité %inline; mais ne doit pas contenir d'autres éléments A |
X|Y | Soit X soit Y doit être présent, mais pas les deux |
X,Y | X et Y doivent être présents dans l'ordre indiqué |
EMPTY | le mot réservé EMPTY indique que l'élément en question ne peut pas avoir de contenu. Généralement, l'élément est composé d'une seule balise, comme par exemple BR ou IMG (voir exemple plus haut) |
#PCDATA | "Parseable Character Data" indique que le contenu est une suite
de caractères. Si #PCDATA est un contenu possible parmi plusieurs, l'élément est dit "à contenu mixte". #PCDATA doit alors être la première des alternatives listées et le groupe d'alternatives doit être optionnel (c-à-d pouvoir apparaître zéro, une ou plusieurs fois. L'astérisque ou le point d'interrogation peuvent être utilisés à cet effet. Exemple: <!ELEMENT texte (#PCDATA|grand|image)*> |
ANY | le mot réservé ANY indique que l'élément en question peut avoir n'importe quel contenu. |
<!ATTLIST NomDElement
NomDAttribut TypeValeurOuEnumeration Defaut
NomDAttribut TypeValeurOuEnumeration Defaut
... >
Le type de valeur d'un attribut peut être :
CDATA | pour indiquer que la valeur de l'attribut est une séquence de caractères (y compris des entités de caractères) |
---|---|
ID | pour indiquer que la valeur de l'attribut est un symbole commençant par une lettre et ne contenant que des lettres, des chiffres, ou les caractères - _ : et . (la valeur doit être unique sur l'ensemble d'un document) |
IDREF | pour indiquer que la valeur de l'attribut est un symbole défini comme valeur de l'attribut ID d'un autre élément de document |
IDREFS | comme IDREF, mais plusieurs valeurs séparées par des espaces sont autorisées |
ENTITY ENTITIES NMTOKEN NMTOKENS |
pour utilisateurs avancés (pas abordé dans le cadre de ce cours) |
énumération | une énumération de valeurs possibles se fait en mettant
entre parenthèses les valeurs séparées par des |. Exemple:
<!ATTLIST TD |
Défaut indique ce qu'il doit advenir si l'attribut en question n'est pas utilisé. Il peut être :
Le symbole prédéfini #IMPLIED | indique que l'application traitant le document fournira la valeur par défaut |
Le symbole prédéfini #REQUIRED | indique l'auteur du document doit définir l'attribut en question |
Le symbole prédéfini #FIXED suivi d'une valeur (chaîne de caractères entre guillemets) | indique que l'attribut ne peut prendre que la valeur mentionnée |
Une des valeurs d'une énumération, ou une chaîne de caractères compatible avec le type associé à l'attribut | indique qu'en l'absence d'indication explicite, l'attribut prendra la valeur indiquée ici |
Il existe des noms d'attributs prédéfinis :
xml:lang | prend des valeurs de type code de langue (p.ex. en ou fr-CH) |
---|---|
xml:space | est de type énumération et ne peut prendre que les valeurs default (indique que l'application traitant le document xml peut traiter les espaces comme elle le désire) ou preserve (indique que l'application traitant le document xml doit conserver les espaces tels quels). |
La déclaration des attributs d'un élément utilisant un de ces attributs prédéfinis doit explicitement mentionner l'attribut prédéfini. Par exemple :
<!ATTLIST UnElement xml:lang NMTOKEN 'en-US'>
<!ATTLIST pre xml:space (preserve) #FIXED preserve>
<!DOCTYPE NomDeLElementRacine SYSTEM "URLduFichierDeDTD">
Note: l'URL de la DTD peut être absolue ou relative. Exemple: le fichierxml_test.xml
(code XML correspondant) pourrait contenir
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE TestLat1 SYSTEM "xml_Lat1.dtd">
<TestLat1>texte contenant une série de lettres
accentuées...</TestLat1>
xml_Lat1.dtd
(code XML correspondant) pourrait contenir
<!-- ce qui suit permet d'utiliser les entites
symboliques de HTML pour les lettres accentuees -->
<!ENTITY % HTMLlat1
PUBLIC "-//W3C//ENTITIES Latin 1 for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
%HTMLlat1;
<!-- ce qui suit indique que l'element TestLat1 peut contenir du texte
ou etre vide -->
<!ELEMENT TestLat1 (#PCDATA)*>
<!ENTITY % HTMLsymbol PUBLIC "-//W3C//ENTITIES Symbols for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
%HTMLsymbol;
<!ENTITY % HTMLspecial PUBLIC "-//W3C//ENTITIES Special for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
%HTMLspecial;
<!DOCTYPE NomElementRacine PUBLIC "DetailsDeLaDTD" "URLFacultativeFichierDTD">
où "DetailsDeLaDTD"
est de la forme :
"préfixe//auteur//description//CodeEn2LettresDeLaLangueUtilisée"
Le préfixe peut être :
ISO | La DTD est un standard ISO |
---|---|
+ | La DTD est un standard approuvé par une autre organisation de standardisation que l'ISO |
- | La DTD n'a pas été approuvée par une organisation de standardisation |
Par exemple, pour XHTML :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
indique que le consortium W3 est l'auteur de cette DTD, qui est rédigée en anglais (pour les commentaires).
Une DTD pour des articles :
<!-- ce qui suit permet d'utiliser tous les elements de HTML -->
<!ENTITY % html PUBLIC
"-//W3C//XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
%html;
<!-- l'element "article" doit contenir, en sequence, un element titre,
un element auteur, un element date, un element lieu et un element texte
-->
<!ELEMENT article (titre, auteur, date, lieu, texte)>
<!ELEMENT titre (#PCDATA)>
<!ELEMENT auteur (#PCDATA)>
<!ELEMENT date (#PCDATA)>
<!ELEMENT lieu (#PCDATA)>
<!-- l'element "texte" peut contenir du texte et des elements "grand"
et "image" en nombre indetermine>
-->
<!ELEMENT texte (#PCDATA|grand|image)*>
<!ELEMENT grand (#PCDATA)>
<!-- l'element "image" doit contenir une balise HTML img et une legende
facultative
-->
<!ELEMENT image (img, (legende)?)>
<!ELEMENT legende (#PCDATA)>
Il n'est toutefois pas recommandé d'inclure ainsi la totalité de la DTD du langage HTML, car cela risquerait d'être assez "indigeste" pour le navigateur. Le document XML pourrait être ainsi :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE article SYSTEM "Exemple.dtd">
<?xml-stylesheet type="text/css" href="Exemple.css"?>
<article
xmlns:html="http://www.w3.org/Profiles/XHTML-transitional">
<titre>Un journaliste accuse, un policier
dément</titre>
<auteur>Alain Connu</auteur>
<date>14 juin 1972</date>
<lieu>banquise</lieu>
<texte>
<grand>Un journaliste de la place
accuse</grand>
les autorités ...
<image>
<html:img html:src="photo.gif" />
<legende>Legende de la
photo</legende>
</image>
...
</texte>
</article>