Schéma XML:Types de données
Un article de WikiTuto.
Sommaire |
Introduction
Ainsi que nous l'avons déjà brièvement signalé, XML Schema permet de spécifier des types de données bien plus finement que le langage DTD. Il distingue notamment types simples et types complexes.
Types simples
Généralités
Les types de données simples ne peuvent comporter ni attributs, ni éléments enfants. Il en existe de nombreux, prédéfinis, mais il est également possible d'en "dériver" de nouveaux (nous reviendrons plus loin sur cette fonctionnalité). Enfin, il est possible de déclarer des "listes" de types.
Bibliothèque de types intégrés
Nombreux sont les types prédéfinis dans la bibliothèque de types intégrés de XML Schema. la figure suivante en donne la hiérarchie, et leur liste détaillée figure sur le site du W3C.
Les types de données les plus simples (les chaînes de caractères) que permettaient les DTDs sont conservés, mais d'autres ont fait leur apparition. On pourra envisager, par exemple, dans un schéma décrivant un bon de commande, la déclaration d'un attribut quantite :
<xsd:attribute name="quantite" type="xsd:positiveInteger" use="default" value="1" />
... qui force la valeur de l'attribut à un être un entier positif. Un bon de commande XML suivant ce schéma, ayant une commande spécifiant quantite="-3" sera alors automatiquement refusé par le système. Un tel document peut dès lors être enregistré directement dans une base de données, sans contrôle supplémentaire sur ce point.
Listes
Les types listes sont des suites de types simples (ou atomiques). XML Schema possède trois types de listes intégrés : NMTOKENS, ENTITIES et IDREFS. Il est également possible de créer une liste personnalisée, par "dérivation" de types existants. Par exemple,
<xsd:simpleType name="numéroDeTéléphone"> <xsd:list itemType="xsd:unsignedByte" /> </xsd:simpleType>
Un élément conforme à cette déclaration serait <téléphone>01 44 27 60 11</téléphone>.
Il est également possible d'indiquer des contraintes plus fortes sur les types simples ; ces contraintes s'appellent des "facettes". Elles permettent par exemple de limiter la longueur de notre numéro de téléphone à 10 nombres. Nous y reviendrons.
Unions
Les listes et les types simples intégrés ne permettent pas de choisir le type de contenu d'un élément. On peut désirer, par exemple, qu'un type autorise soit un nombre, soit une chaîne de caractères particuliers. Il est possible de le faire à l'aide d'une déclaration d'union. Par exemple, sous réserve que le type simple numéroDeTéléphone ait été préalablement défini (voir précédemment), on peut déclarer...
<xsd:simpleType name="numéroDeTéléphoneMnémoTechnique"> <xsd:union memberTypes="xsd:string numéroDeTéléphone" /> </xsd:simpleType>
Les éléments suivants sont alors des "instances" valides de cette déclaration :
<téléphone>18</téléphone> <téléphone>Pompiers</téléphone>
Les types complexes
Introduction
Un élément de type simple ne peut contenir de sous-élément. Il est nécessaire pour cela de le déclarer de type "complexe". On peut alors déclarer, des séquences d'éléments, des types de choix ou des contraintes d'occurences
Séquences d'éléments
Nous savons déjà comment, dans une DTD, nous pouvons déclarer un élément comme pouvant contenir une suite de sous-éléments, dans un ordre déterminé. Il est bien sûr possible de faire de même avec un schéma.
On utilise pour ce faire l'élément xsd:sequence, qui reproduit l'opérateur , du langage DTD. Ainsi...
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nom" type="xsd:string" />
<xsd:element name="prénom" type="xsd:string" />
<xsd:element name="dateDeNaissance" type="xsd:date" />
<xsd:element name="adresse" type="xsd:string" />
<xsd:element name="adresseElectronique" type="xsd:string" />
<xsd:element name="téléphone" type="numéroDeTéléphone" />
</xsd:sequence>
</xsd:complexType>
... est équivalent à une déclaration d'élément, dans une DTD, où apparaîtrait (nom, prénom, dateDeNaissance, adresse, adresseElectronique, téléphone).
Choix d'élément
On peut vouloir modifier la déclaration de type précédente en stipulant qu'on doive indiquer soit l'adresse d'une personne, soit son adresse électronique. Pour cela, il suffit d'utiliser un élément xsd:choice :
<xsd:complexType name="typePersonne">
<sequence>
<xsd:element name="nom" type="xsd:string" />
<xsd:element name="prénom" type="xsd:string" />
<xsd:element name="dateDeNaissance" type="xsd:date" />
<xsd:choice>
<xsd:element name="adresse" type="xsd:string" />
<xsd:element name="adresseElectronique" type="xsd:string" />
</xsd:choice>
</sequence>
<xsd:element name="téléphone" type="numéroDeTéléphone" />
</xsd:complexType>
Ce connecteur a donc les mêmes effets que l'opérateur | dans une DTD.
L'élément all
Cet élément est une nouveauté par rapport aux DTD. Il indique que les éléments enfants doivent apparaître une fois (ou pas du tout), et dans n'importe quel ordre. Cet élément xsd:all doit être un enfant direct de l'élément xsd:complexType. Par exemple...
<xsd:complexType>
<xsd:all>
<xsd:element name="nom" type="xsd:string" />
<xsd:element name="prénom" type="xsd:string" />
<xsd:element name="dateDeNaissance" type="xsd:date" />
<xsd:element name="adresse" type="xsd:string" />
<xsd:element name="adresseElectronique" type="xsd:string" />
<xsd:element name="téléphone" type="numéroDeTéléphone" />
</xsd:all>
</xsd:complexType>
... indique que chacun de ces éléments peut apparaître une fois ou pas du tout (équivalent de l'opérateur ? dans une DTD), et que l'ordre des éléments n'a pas d'importance (cela n'a pas d'équivalent dans une DTD).
Les fils de l'élément xsd:all doivent impérativement apparaître au plus une fois, ce qui signifie que deux attributs, que nous allons voir maintenant, doivent être renseignés. Ces attributs sont minoccurs et maxoccurs.
Indicateurs d'occurences
Dans une DTD, un indicateur d'occurence ne peut prendre que les valeurs 0, 1 ou l'infini. On peut forcer un élément sselt à être présent 378 fois, mais il faut pour cela écrire (sselt, sselt..., sselt, sselt) 378 fois. XML Schema permet de déclarer directement une telle occurence, car tout nombre entier non négatif peut être utilisé. Pour déclarer qu'un élément peut être présent un nombre illimité de fois, on utilise la valeur unbounded. Les attributs utiles sont minOccurs et maxOccurs, qui indiquent respectivement les nombres minimal et maximal de fois où un élément peut apparaître. Le tableau suivant récapitule les possibilités :
| Dans une DTD | Valeur de minOccurs | Valeur de maxOccurs |
|---|---|---|
| * | 0 | unbounded |
| ? | 0 | 1 (pas nécessaire, valeur par défaut) |
| rien | 1 (pas nécessaire, valeur par défaut) | 1 (pas nécessaire, valeur par défaut) |
Table 2. Liste des indicateurs d'occurence.
Création de type complexe à partir de types simples
Il est possible également de créer un type complexe à partir d'un type simple.
On peut avoir besoin de définir un élément contenant une valeur simple, et possédant un attribut, comme <poids unite="kg">67</poids>, par exemple. Un tel élément ne peut pas être déclaré de type simple, car il contient un attribut. Il faut dériver un type complexe à partir du type simple positiveInteger :
<xsd:complexType name="typePoids">
<xsd:simpleContent>
<xsd:extension base="xsd:positiveInteger">
<xsd:attribute name="unite" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
L'élément <xsd:simpleContent indique que le nouvel élément ne contient pas de sous-élément.




