Chaque document XML doit être bien formé. En d'autres termes, il doit satisfaire un minimum d'exigences de conformité. Si un document n'est pas bien formé, il ne peut être considéré comme un document XML. Revoici les critères minimums :
Un document XML bien formé peut aussi être valide. Un document XML valide est un document bien formé qui répond en outre à deux exigences.
La création d'un document XML valide semble accompagnée de son lot de complication : d'abord, il faut définir complètement la structure du document dans une DTD, ensuite il faut créer le document lui-même dans le respect des spécifications de la DTD.
Si toutefois, vous voulez être certain que votre document se conforme à une structure spécifique ou à un ensemble de standards, l'inclusion d'une DTD définissant cette structure permet à un processeur XML (tel que XERCES) de vérifier si votre document est conforme à la structure. En d'autres termes, une DTD fournit un prototype standard au processeur, de sorte qu'en vérifiant la validité du document il peut appliquer la structure désirée et garantir que le document respecte les normes requises.
Rendre valides des documents XML est particulièrement utile pour assurer une uniformité dans un groupe de documents similaires. En fait, la norme XML définit une DTD comme « une grammaire pour une classe de documents ».
Si vous ne devez travailler qu'avec un seul document XML, vous pouvez mettre en uvre votre DTD directement dans le même document dès le début avant les premières écritures de vos balises XML. Dans ce cas là, il s'agit d'une DTD interne. Dans la majorité des cas, il est préférable de spécifier votre DTD dans un fichier séparé pour qu'il permette la validité d'un ensemble de documents XML. Il s'agit alors d'une DTD externe. Il existe deux types de DTD externes :
Les DTD externes sont spécifiées à l'aide d'une déclaration « DOCTYPE » contenant une URI qui identifie l'emplacement de la DTD.
La déclaration « DOCTYPE » doit se trouver dans le prologue d'un document XML, donc après la déclaration XML, mais avant l'élément racine.
Les déclarations de marquage décrivent la structure logique du document ; en d'autres termes, elles définissent les éléments du document, les attributs et d'autres caractéristiques.
Une DTD peut contenir les types de déclarations de marquage suivant :
Une déclaration de type d'élément indique le nom de l'élément (de la balise XML) ainsi que le contenu autorisé de l'élément (spécifiant souvent l'ordre dans lequel les éléments de sa filiation peuvent apparaître). Prise ensemble, les déclarations des éléments dans la DTD similaire à un schéma de base de données tracent la carte de toute la structure logique du document. En d'autres termes, les déclarations des éléments indiquent le nom des éléments que le document contient, l'ordre des éléments et les spécifications de contenu des éléments.
Chacun de ces éléments est spécifié à l'aide d'une déclaration « ELEMENT », composé d'un nom d'élément suivi d'une description du contenu de l'élément, sous la forme suivante :
ATTENTION : chaque élément autorisé dans le corps d'un document XML doit être déclaré. Après avoir déclaré un élément dans la DTD, vous avez le droit de vous en servir dans le corps d'un document XML associé à une DTD.
Le modèle de contenu le plus simple est probablement celui qui indique qu'un élément ne doit contenir que des données textuelles analysées, c'est-à-dire, du texte brut contenant éventuellement des références d'entités comme > ; ou < ; (équivalent à < et > ). #PCDATA ne doit contenir aucun autre sous-élément, c'est-à-dire aucun élément enfant. Ce type de contenu représente finalement les données qui existent entre les balises XML les plus imbriquées. Nous pouvons trouver soit un texte, soit un nombre, mais ce nombre n'est pas interprété en temps que tel, il correspond également à une suite de caractères.
Par exemple, cette déclaration renseigne un élément muméro_téléphone contenant du texte, mais ne pouvant pas être décrits par des chiffres représentant le code zone, le nombre et l'extension.
Un autre modèle de contenu simple est celui indiquant qu'un élément doit avoir exactement un sous-élément d'un type donné. Dans ce cas, le modèle de contenu se composera simplement du nom du sous-élément, entre parenthèses.
Par exemple, cette déclaration indique qu'un élément fax doit contenir exactement un seul élément numéro_téléphone. Un élément fax ne peut rien contenir en dehors d'un élément numéro_téléphone et il ne peut pas en contenir plus ou moins de un.
En pratique, un modèle de contenu qui ne désigne un seul sous-élément est peu fréquent. La plupart des éléments contiennent à la fois des données textuelles analysées et éventuellement plusieurs sous-éléments. La façon la plus simple pour indiquer plusieurs sous-éléments est de les séparer par une virgule. C'est ce que l'on appelle une séquence. Elle indique que les éléments nommés doivent apparaître dans un ordre spécifique.
Par exemple, cette déclaration d'élément indique qu'un élément livre doit contenir exactement un sous-élément titre suivi exactement par un autre sous-élément auteur suivi exactement par un autre sous-élément pages.
Toutes les instances d'un élément donné n'ont pas exactement le même nombre de sous-éléments. Vous pouvez compléter par l'un des trois suffixes le nom d'un élément dans le modèle de contenu pour indiquer combien d'instances de cet élément sont attendues à cet endroit.
Cette déclaration indique qu'un élément livre doit contenir l'élément titre, peut ou ne pas contenir les éléments auteur et pages.
Vous pouvez autoriser plusieurs auteurs en positionnant un astérisque après auteur.
Un choix est une liste de noms d'éléments séparés par des barres verticales. Dans ce cas de figure, nous devons exclusivement spécifier un élément parmi la liste proposée et pas autre chose.
Cette déclaration indique qu'un élément Contact contient un des trois sous-élément possibles Adresse , Mail ou Téléphone.
Pris séparément, les choix, les séquences et les suffixes sont assez limités. Cependant, ils peuvent être imbriqués de manière complexe pour décrire à peu près n'importe quel modèle de contenu convenable. Un choix ou une séquence peuvent être indifféremment insérés à l'intérieur de parenthèses. Les parenthèses peuvent être suivies par ? , * ou +. Vous pouvez également imbriquer des éléments mis entre parenthèses dans d'autre choix ou séquences.
Pour déclarer un élément pouvant contenir des données textuelles et, en outre, un ou plusieurs (ou aucun) éléments enfants, listez chaque type d'élément enfant (afin de proposer le choix) à la suite de #PCDATA dans le modèle de contenu, en séparant les items à l'aide du caractère « | » et en insérant un astérisque à la suite du modèle de contenu.
Cette déclaration indique qu'un élément définition peut contenir des données textuelles analysées et des sous-éléments Nota. Elle ne spécifie ni dans quel ordre ils apparaissent, ni le nombre de chaque instance. Cette déclaration autorise une définition à avoir un, aucun ou plusieurs sous-éléments Nota, ou zone de texte.
Autre exemple :
Certains éléments, appelés éléments vides, ne possèdent aucun contenu. Les éléments vides sont quelque fois écris sous la forme d'une seule balise avec un « /> » à la fin. Les balises vides possèdent systématiquement des attributs qui définissent le comportement souhaité.
Ces éléments vides sont déclarés en utilisant le mot-clé EMPTY pour le modèle de contenu :
Cette déclaration indique simplement que l'élément image doit être vide, et non qu'il doit être écrit avec un marqueur d'élément vide. Etant donné cette déclaration, voilà également un élément image valide :
Si un élément est vide, alors il ne peut rien contenir, pas même un espace blanc :
Vous pouvez employer le mot-clé ANY pour indiquer que l'élément peur avoir tout type de contenu légal. En d'autres termes, un élément de ce type peut contenir zéro, un ou plusieurs éléments enfants, dans n'importe quel ordre ou avec n'importe quel nombre de répétitions, avec ou sans données textuelles. C'est la spécification la plus souple ; elle crée un élément sans contrainte de contenu.
Outre le fait de déclarer ses éléments, un document valide doit déclarer tous les attributs des éléments. Cela est réalisé avec les déclarations ATTLIST. Un seul ATTLIST peut déclarer plusieurs attributs pour un seul type d'élément. Toutefois, si le même attribut est répété dans plusieurs éléments, il doit être déclaré séparément pour chaque élément où il doit apparaître. Il est également possible d'utiliser des appels d'entité paramètre pour rendre cette répétition moins lourde.
Une simple instruction ATTLIST peut déclarer différents attributs d'une même balise.
Cette déclaration indique que les attributs source, largeur, hauteur sont obligatoires. Cependant, l'attribut alternative est optionnel et peut être omis par certains éléments image. Ces quatre attributs sont déclarés contenir des données textuelles, le type d'attribut le plus générique.
Le type d'attribut est le second composant obligatoire dans une définition d'attribut. Il spécifie le genre de valeur que vous pouvez affecter à l'attribut dans l'élément concerné. Dans les documents XML bien formés, les valeurs des attributs peuvent être n'importe qu'elle chaîne de texte. Les seules restrictions sont les occurrences de « < » et « & » qui doivent être échappées par < ; et & ; et quelque soit le type de caractère utilisé pour délimiter la valeur (simple ou double quottes), il doit aussi être échappé. Cependant, la DTD permet, dans une certaine mesure, des déclarations plus fortes sur le contenu de la valeur.
Dix types d'attributs existent dans XML :
Seuls ces dix types d'attribut sont autorisés. Une DTD ne peut pas indiquer que la valeur d'un attribut doit être, par exemple, un entier ou une date entre 1975 et 2004.
Outre le fait de fournir un type de données, chaque déclaration ATTLIST inclut une déclaration par défaut pour cet attribut. Quatre possibilités existent pour cette option.
Une valeur d'attribut CDATA peut contenir n'importe quelle chaîne de caractères possible dans la valeur d'un attribut XML bien formé. C'est le type d'attribut le plus général. Vous pouvez utiliser ce type pour un attribut source d'un élément image puisqu'il n'a pas de forme de texte particulière dans un tel attribut :
Il est impossible de spécifier dans une DTD le type de données à affecter dans un attribut. Par exemple, vous ne pouvez pas obliger un attribut particulier à contenir une date et un autre un nombre entier. La seule manière de restreindre les valeurs des attributs consiste à faire appel à des « tokens » de noms XML valides.
Les « tokens » de nom XML sont composés d'une ou plusieurs lettres, chiffres, points « . », tiret « - », ou souligné « _ ». En revanche les espaces ne sont pas autorisés.
Ce type d'attribut est identique au type NMTOKEN à l'exception près que la valeur peut inclure plusieurs « tokens » de nom (séparés par des espaces) tous à l'intérieur d'une seule chaîne entre guillemets. Par exemple, vous pouvez utiliser ce type pour décrire l'attribut dates d'un élément concerts, si les dates sont de la forme :
26-02-2004 (jj-mm-aaaa).
L'énumération est le seul type d'attribut n'étant pas représenté par un mot clé XML. Le modèle de contenu est plutôt une liste de toutes les valeurs possibles pour un attribut, séparées par des barres verticales. La valeur associée à un type énuméré doit être une chaîne entre guillemets conforme aux règles du XML.
Trois catégories de livres dans la même bibliothèque.
La déclaration précédente indique que la valeur de l'attribut catégorie doit posséder uniquement l'une des trois valeurs désignées par la liste : BD, Fiction, Roman. La balise suivante est donc valide :
Il est possible de préciser une valeur par défaut qui doit être spécifiée entre guillemets :
Ce type indique que la valeur d'un attribut doit être unique dans un document. Aucun attribut ID ne peut donc prendre une valeur déjà affectée à un autre attribut ID . Pour implémenter ce mécanisme, il convient de respecter certaines règles :
Dans cet exemple, le numéro de sécurité sociale offre un caractère unique pour chaque individu. Il paraît approprié d'utiliser le type ID pour l'attribut numéro_sécu de l'élément employé . (Attention, il ne faut pas commencer par un chiffre) :