XSD est une alternative plus puissante aux DTD pour valider des documents XML. Elle offre un typage fort, le support des namespaces, et une syntaxe XML native. XSD permet de définir des contraintes précises sur le contenu des éléments et attributs.
Un schéma XSD est lui-même un document XML avec un namespace spécifique.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Déclaration de l'élément racine -->
<xs:element name="bibliotheque" type="BibliothequeType"/>
<!-- Définition du type complexe -->
<xs:complexType name="BibliothequeType">
<xs:sequence>
<xs:element name="livre" type="LivreType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Type pour un livre -->
<xs:complexType name="LivreType">
<xs:sequence>
<xs:element name="titre" type="xs:string"/>
<xs:element name="auteur" type="xs:string" maxOccurs="unbounded"/>
<xs:element name="prix" type="PrixType"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:ID" use="required"/>
</xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<bibliotheque
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="bibliotheque.xsd">
<livre isbn="L001">
<titre>Introduction XML</titre>
<auteur>Jean Dupont</auteur>
<prix devise="EUR">29.99</prix>
</livre>
</bibliotheque>
xsi:noNamespaceSchemaLocation : pour un schéma sans namespacexsi:schemaLocation : pour un schéma avec namespace (paire namespace + URI)Contient uniquement du texte (pas d'éléments enfants). Peut avoir des restrictions (facettes).
<xs:simpleType name="NoteType">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="20"/>
</xs:restriction>
</xs:simpleType>
Peut contenir des éléments enfants et/ou des attributs.
<xs:complexType name="PersonneType">
<xs:sequence>
<xs:element name="nom" type="xs:string"/>
<xs:element name="prenom" type="xs:string"/>
</xs:sequence>
<xs:attribute name="id" type="xs:ID"/>
</xs:complexType>
Les facettes permettent de restreindre les valeurs acceptées par un type simple.
| Facette | Description | Exemple |
|---|---|---|
minLength | Longueur minimale | <xs:minLength value="2"/> |
maxLength | Longueur maximale | <xs:maxLength value="50"/> |
length | Longueur exacte | <xs:length value="10"/> |
minInclusive | Valeur min (incluse) : ≥ | <xs:minInclusive value="0"/> |
maxInclusive | Valeur max (incluse) : ≤ | <xs:maxInclusive value="100"/> |
minExclusive | Valeur min (exclue) : > | <xs:minExclusive value="0"/> |
maxExclusive | Valeur max (exclue) : < | <xs:maxExclusive value="100"/> |
pattern | Expression régulière | <xs:pattern value="[A-Z]{2}[0-9]+"/> |
enumeration | Liste de valeurs autorisées | <xs:enumeration value="H"/> |
fractionDigits | Nombre de décimales | <xs:fractionDigits value="2"/> |
totalDigits | Nombre total de chiffres | <xs:totalDigits value="5"/> |
whiteSpace | Gestion des espaces | <xs:whiteSpace value="collapse"/> |
<!-- Type pour un code postal français -->
<xs:simpleType name="CodePostalType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{5}"/>
</xs:restriction>
</xs:simpleType>
<!-- Type pour un email -->
<xs:simpleType name="EmailType">
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9._]+@[a-zA-Z0-9.]+\.[a-zA-Z]{2,}"/>
</xs:restriction>
</xs:simpleType>
<!-- Énumération de valeurs -->
<xs:simpleType name="SexeType">
<xs:restriction base="xs:string">
<xs:enumeration value="Homme"/>
<xs:enumeration value="Femme"/>
<xs:enumeration value="Autre"/>
</xs:restriction>
</xs:simpleType>
<!-- Note entre 0 et 20 avec 2 décimales max -->
<xs:simpleType name="NoteType">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="20"/>
<xs:fractionDigits value="2"/>
</xs:restriction>
</xs:simpleType>
Contrairement aux DTD (?, +, *), XSD permet une cardinalité précise.
| Attribut | Description | Valeur par défaut |
|---|---|---|
minOccurs | Nombre minimum d'occurrences | 1 |
maxOccurs | Nombre maximum d'occurrences | 1 |
maxOccurs="unbounded" | Nombre illimité | - |
| DTD | XSD | Signification |
|---|---|---|
element | minOccurs="1" maxOccurs="1" | Exactement 1 (défaut) |
element? | minOccurs="0" maxOccurs="1" | 0 ou 1 |
element+ | minOccurs="1" maxOccurs="unbounded" | 1 ou plus |
element* | minOccurs="0" maxOccurs="unbounded" | 0 ou plus |
| - | minOccurs="2" maxOccurs="5" | Entre 2 et 5 |
Éléments dans un ordre précis.
Équivalent DTD : (a, b, c)
<xs:sequence>
<xs:element name="nom"/>
<xs:element name="prenom"/>
</xs:sequence>
Un seul élément parmi plusieurs.
Équivalent DTD : (a | b | c)
<xs:choice>
<xs:element name="carte"/>
<xs:element name="especes"/>
</xs:choice>
Tous les éléments dans n'importe quel ordre.
Pas d'équivalent DTD.
<xs:all>
<xs:element name="nom"/>
<xs:element name="email"/>
</xs:all>
xs:sequence ou xs:choice imbriqués<!-- Déclaration d'attributs -->
<xs:attribute name="id" type="xs:ID" use="required"/>
<xs:attribute name="langue" type="xs:string" default="fr"/>
<xs:attribute name="version" type="xs:string" fixed="1.0"/>
<xs:attribute name="note" type="NoteType"/> <!-- type personnalisé -->
Attribut use | Signification | Équiv. DTD |
|---|---|---|
required | Attribut obligatoire | #REQUIRED |
optional | Attribut optionnel (par défaut) | #IMPLIED |
prohibited | Attribut interdit (pour restriction) | - |
| Attribut | Signification | Équiv. DTD |
|---|---|---|
default="val" | Valeur par défaut | "val" |
fixed="val" | Valeur fixe non modifiable | #FIXED "val" |
| Type | Description | Exemples valides |
|---|---|---|
xs:string | Chaîne de caractères | "Bonjour", "123" |
xs:int / xs:integer | Entier | 42, -17, 0 |
xs:decimal | Nombre décimal | 19.99, -3.14 |
xs:float / xs:double | Nombre flottant | 3.14E10 |
xs:boolean | Booléen | true, false, 1, 0 |
xs:date | Date (YYYY-MM-DD) | 2026-01-08 |
xs:time | Heure (HH:MM:SS) | 14:30:00 |
xs:dateTime | Date et heure | 2026-01-08T14:30:00 |
xs:ID | Identifiant unique | id123, _item |
xs:IDREF | Référence à un ID | id123 |
xs:anyURI | URI/URL | https://exemple.org |
xs:language | Code langue | fr, en-US |
L'extension permet d'ajouter des éléments ou attributs à un type existant.
<!-- Type de base -->
<xs:complexType name="PersonneType">
<xs:sequence>
<xs:element name="nom" type="xs:string"/>
<xs:element name="prenom" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<!-- Type étendu (hérite de PersonneType) -->
<xs:complexType name="EmployeType">
<xs:complexContent>
<xs:extension base="PersonneType">
<xs:sequence>
<xs:element name="poste" type="xs:string"/>
<xs:element name="salaire" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="matricule" type="xs:ID" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
La restriction permet de limiter les valeurs acceptées par un type.
<!-- Restriction d'un simpleType -->
<xs:simpleType name="AgeType">
<xs:restriction base="xs:positiveInteger">
<xs:maxInclusive value="150"/>
</xs:restriction>
</xs:simpleType>
<!-- Restriction d'un complexType -->
<xs:complexType name="PersonneRestreinteType">
<xs:complexContent>
<xs:restriction base="PersonneType">
<xs:sequence>
<xs:element name="nom" type="xs:string"/>
<!-- prenom retiré -->
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
Pour un élément avec contenu texte et des attributs :
<xs:complexType name="PrixType">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="devise" type="xs:string" default="EUR"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Utilisation -->
<prix devise="USD">29.99</prix>
<!-- Déclaration globale d'un élément -->
<xs:element name="adresse" type="AdresseType"/>
<!-- Référence à l'élément global -->
<xs:complexType name="PersonneType">
<xs:sequence>
<xs:element name="nom" type="xs:string"/>
<xs:element ref="adresse"/> <!-- Utilise la définition globale -->
</xs:sequence>
</xs:complexType>
<!-- Groupe d'éléments réutilisable -->
<xs:group name="ContactGroup">
<xs:sequence>
<xs:element name="email" type="xs:string"/>
<xs:element name="telephone" type="xs:string"/>
</xs:sequence>
</xs:group>
<!-- Utilisation du groupe -->
<xs:complexType name="ClientType">
<xs:sequence>
<xs:element name="nom" type="xs:string"/>
<xs:group ref="ContactGroup"/>
</xs:sequence>
</xs:complexType>
<!-- Groupe d'attributs réutilisable -->
<xs:attributeGroup name="MetadonneesGroup">
<xs:attribute name="creePar" type="xs:string"/>
<xs:attribute name="creeDate" type="xs:date"/>
</xs:attributeGroup>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Schéma XSD pour gérer des informations étudiants -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Élément racine -->
<xsd:element name="universite" type="UniversiteType"/>
<!-- Type pour l'université -->
<xsd:complexType name="UniversiteType">
<xsd:sequence>
<xsd:element name="etudiant" type="EtudiantType" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="nom" type="xsd:string" use="required"/>
</xsd:complexType>
<!-- Type complexe pour un étudiant -->
<xsd:complexType name="EtudiantType">
<xsd:sequence>
<xsd:element name="nom" type="NomType"/>
<xsd:element name="prenom" type="xsd:string"/>
<xsd:element name="email" type="EmailType" minOccurs="0"/>
<xsd:element name="cours" type="CoursType" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:ID" use="required"/>
<xsd:attribute name="sexe" type="SexeType"/>
</xsd:complexType>
<!-- Type pour un cours avec note -->
<xsd:complexType name="CoursType">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="note" type="NoteType"/>
<xsd:attribute name="credits" type="xsd:positiveInteger"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!-- Types simples avec restrictions -->
<xsd:simpleType name="NomType">
<xsd:restriction base="xsd:string">
<xsd:minLength value="2"/>
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="NoteType">
<xsd:restriction base="xsd:decimal">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="20"/>
<xsd:fractionDigits value="2"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="SexeType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="H"/>
<xsd:enumeration value="F"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="EmailType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[a-zA-Z0-9._]+@[a-zA-Z0-9.]+\.[a-zA-Z]{2,}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Testez vos connaissances sur les schémas XSD.
Q1. Quelle facette permet de définir une expression régulière ?
Q2. Quel attribut permet un nombre illimité d'occurrences ?
Q3. Pour un élément optionnel (0 ou 1), quelle combinaison utiliser ?
Q4. Quel compositeur permet les éléments dans n'importe quel ordre ?
Q5. Pour ajouter des attributs à un élément contenant du texte simple, on utilise :
Q6. Quelle est la valeur par défaut de minOccurs et maxOccurs ?