Cours langage XML Schémas
Cours langage XML Schémas avec exercices corrigés
Définition : Schéma
Un schéma est une description de la structure que doit respecter un document lui faisant référence, c'est à dire qu'il établit la liste des éléments XML autorisés (avec leurs attributs), ainsi que l'agencement possible de ces éléments.
On parle aussi de grammaire, au sens où le schéma définit l'enchaînement autorisé des balises et vient en complément de la syntaxe XML (qui elle est indépendante d'un schéma particulier).
Définition : Document valide
Un document XML * bien formé est dit valide pour un schéma donné s'il respecte les règles structurelles imposées par ce schéma.
Ce contrôle de la structure permet :
- De s'assurer l'homogénéité structurelle des documents de même type.
- Le traitement automatique d'un ensemble de documents de même type (mise en forme, stockage, extraction d'informations...).
- La création de formats standard et leur respect.
Exemple : Exemples de langages de schéma
Il existe plusieurs langages de définition schéma, mais les trois principaux sont :
- Document Type Définition (W3C) : Un langage hérité de SGML qui fait partie du standard XML
- W3C XML Schema (W3C) : Une alternative aux DTD destiné à moderniser et compléter ce langage historique
- Relax NG (OASIS, ISO) : Une autre alternative, compromis entre W3C XML Schema et DTD
W3C XML Schema
- Document Type Definition
Le formalisme de définition de schéma DTD est le premier qui a été introduit dès la première version du standard XML. Il est en fait intégré au standard W3C de XML.
Il est directement hérité de la norme SGML.
Les DTDs utilisent un langage spécifique (non XML) pour définir les règles structurelles. Un fichier de DTD peut contenir principalement deux types de déclarations :
- des déclarations d'éléments, indiquent les éléments pouvant être inclus dans un document et l'organisation du contenu de chaque élément (éléments fils ou texte).
- des déclarations d'attributs, définissent les attributs pouvant être associés à un élément ainsi que leur type.
Exemple : Exemple de DTD
<!ELEMENT document paragraphe
( +)>
<!ATTLIST document type CDATA #REQUIRED <!ELEMENT paragraphe #PCDATA
Lorem ipsum dolor sit amet. Consectetur adipiscing elit. Sed do eiusmod tempor.
Exemple : Exemple de document XML valide
- W3C XML Schema
Les XML Schema ont été proposés par le W3C pour permettre de dépasser les limites des DTD. …/XML/Schema
On notera en particulier :
- une syntaxe XML
- l'extension de l'expression des règles d'organisation structurelle (héritage, réutilisation, etc.)
- l'ajout d'un langage de typage des éléments (particulièrement utile pour les format XML orientés données)
Exemple : Exemple de DTD
<!ELEMENT document (paragraphe+)> <!ATTLIST document type CDATA #REQUIRED <!ELEMENT paragraphe #PCDATA
( )>
=
=
= =
= =
= =
Exemple : Exemple de W3C XML Schema correspondant
- Regular Language for XML Next Generation
RelaxNG (REgular LAnguage for XML Next Generation) est un langage de schéma XML.
- RelaxNG est une alternative aux DTD et à W3C XML Schema, qui combine les avantages de ces deux autres langages.
- RelaxNG est un standard OASIS et une norme ISO/CEI.
- Deux syntaxes : une syntaxe XML (alternative à W3C Schema) et une syntaxe compacte (alternative aux DTD).
- RelaxNG ne définit que la structure (comme les DTD) et utilise W3C XML Schema pour le typage des données.
…
Le standard est porté par James Clark depuis ses travaux sur Trex (il est issu de la fusion de Trex et Relax de Murata Makoto).
Exemple : Exemple de schémas publics définis en Relax NG
- OpenDocument (format bureautique) - DocBook (format documentaire) - Atom (syndication)
Exemple : Exemple de schéma RelaxNG correspondant (syntaxe XML)
http://relaxng.org/ns/structure/1.0">
=
=
=
=
Exemple : Exemple de schéma RelaxNG correspondant (syntaxe compacte)
start = element document { attribute type {text}, element paragraphe {text}+
Exemple : Autre exemple de schéma RelaxNG correspondant (syntaxe XML, patterns nommés)
=
=
=
=
=
=
Exemple : Autre exemple de schéma RelaxNG correspondant (syntaxe compacte, patterns nommés)
start = document
document = element document {attribute type {text}, paragraphe+ } paragraphe = element paragraphe {text}
Définition de type de1. Déclaration d'éléments
Syntaxe : Déclaration d'éléments
Les déclarations d'éléments sont de la forme :
1 <!ELEMENT nom (modèle)>
où :
- Le nom obéit aux mêmes règles que les noms dans les balises, c'est à dire commençant par un caractère alphabétique (ou un tiret bas) suivi des caractères alphanumériques, point ou tiret bas.
- Le modèle décrit la combinaison d'éléments et de texte qui pourra être contenue dans cet élément :
- (nom d'un ou plusieurs élément fils)
Indique que l'élément peut contenir un ou des fils ayant le nom indiqué.
- (#PCDATA)
Indique la possibilité de contenir un flot de caractères (Parsed Character Data).
Exemple : Exemple de déclaration d'éléments
...
Syntaxe : Séparateur de structuration
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 :
,Indique une relation d'ordre (connecteur logique AND avec une notion d'ordre) : si par exemple si le modèle est (x,y) alors l'élément x devra être présent, et ce avant l'élément y.
Indique une alternative (connecteur logique "ou exclusif" XOR). Le modèle (x|y) indique "soit x soit y".
L'utilisation de parenthèses permet de créer des sous-listes dans la liste principale pour lesquelles les suffixes de cardinalité sont également applicables.
Exemple : Exemple de déclaration de deux éléments fils ordonnés
<!ELEMENT texte (titre, paragraphe)> <!ELEMENT titre (#PCDATA)> <!ELEMENT paragraphe (#PCDATA)>
Ceci est le flux de caractères du titre
Ceci est le flux de caractères du paragraphe
Exemple : Exemple de déclaration d'alternative
<!ELEMENT texte ((titre | accroche), paragraphe)> <!ELEMENT titre (#PCDATA)> <!ELEMENT accroche (#PCDATA)> <!ELEMENT paragraphe (#PCDATA)>
Syntaxe : Suffixes de cardinalité
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.
Exemple : Exemple général
Les éléments x, y, z1 et z2 sont représentés vides pour alléger l'exemple.
1 <!ELEMENT mon_elem (x?, y*, (z1, z2)+)>
permet :
...
Attention : Élément racine
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.
- Déclaration d'éléments EMPTY et ANY
Syntaxe : Element de type ANY
1 <!ELEMENT nom_element ANY>
L'élément pourra contenir des flots de caractères ainsi que n'importe quels éléments déclarés par ailleurs.
Syntaxe : Element de type EMPTY
Il est possible de déclarer un élément vide en utilisant la syntaxe EMPTY :
1 <!ELEMENT nom_element EMPTY>
L'élément doit être vide. Il contiendra néanmoins généralement des attributs.
Remarque
ANY et EMPTY ne sont pas combinables avec d'autres définitions d'éléments fils, mais sont compatibles avec des définitions d'attributs.
Exemple : Exemple 1 : Le paramètre ANY
<!ELEMENT monElement1 ANY>
<!ELEMENT monElement2 EMPTY>
permet :
bonjour au revoir
Exemple : Exemple 2 : Le paramètre EMPTY
<!ELEMENT monElement1 EMPTY> permet :
ou
...
- Déclarations de listes d'attributs
Syntaxe : Déclaration d'attribut
Les déclarations d'attributs correspondent à la forme générale :
1 <!ATTLIST nom-élément nom-attribut type-attribut déclaration-de-contrainte> où :
- nom-élément :
Nom de l'élément XML * pour lequel les attributs déclarés seront applicables.
- nom-attribut :
Nom de l'attribut, des éléments différents peuvent avoir des attributs de même nom sans qu'il
y ait de confusion possible car un attribut est toujours déclaré en même temps que l'élément auquel il est attaché.
- type-attribut :
Les deux types principaux sont :
- CDATA
L'attribut aura pour valeur une chaîne de caractères.
- Liste de choix
Une liste de noms symboliques correspondant aux valeurs possibles pour l'attribut et
se présentant sous la forme : (choix1 | choix2 | ... | choixN) .
- déclaration-de-contrainte :
Les deux formes principales de contrainte sont :
- #REQUIRED
L'attribut est obligatoire. - #IMPLIED
L'attribut est facultatif.
Remarque : Déclaration de liste d'attributs
La syntaxe ATTLIST permet de déclarer des listes d'attributs, car il est possible de répéter le pattern : nom-attribut type-attribut déclaration-de-contrainte.
Exemple : Déclaration de liste d'attributs
Complément : Autres types d'attributs
En plus des types CDATA et "liste de choix", les attributs peuvent avoir les types suivants : - ID ou IDREF
Sont utilisés pour définir des liens à l'intérieur d'un document, ID identifiant de manière unique tous les éléments pouvant être référencés et IDREF indiquant la référence à cet identifiant.
- NMTOKEN ou NMTOKENS
Permet à l'attribut de prendre pour valeur un ou des noms symboliques quelconques, formés de caractères alphanumériques.
- ENTITY ou ENTITIES
L'attribut prendra pour valeur le nom d'une ou plusieurs entités externes non XML (images...).
- NOTATION
Est utilisé pour des éléments ayant un contenu non XML, l'attribut aura alors pour valeur le nom de l'application qui a été associée à l'application externe traitant le type de contenu concerné lors d'une déclaration de type NOTATION.
Complément : Autres déclarations de contraintes
En plus des déclarations #IMPLIED et #REQUIRED, les attributs peuvent avoir les déclaration de contrainte :
- Valeur par défaut
Indique la valeur par défaut prise par l'attribut (en accord avec son type) s'il n'est pas renseigné. L'attribut peut donc être renseigné ou non (comme un #IMPLIED), mais s'il ne l'est pas il prend la valeur par défaut spécifiée. Se note 'valeur'.
- #FIXED 'valeur'
L'attribut prend toujours la valeur indiquée, il est "constant". Il doit donc toujours être renseigné (comme un #REQUIRED), mais toujours avec la même valeur.
Complément : Voir aussi
ID et REFID (cf. p.12)
- Identifiants et références (ID et IDREF)
Définition : Élément identifié par un attribut identifiant (ID)
Les attributs de type ID permettent d'identifier de façon unique un élément. La valeur d'un attribut de type ID est unique parmi toutes les valeurs des attributs ID de tout le document (sinon le document n'est pas valide, principe d'unicité).
On notera également que:
- la valeur d'un attribut ID est de type NMTOKEN
- un élément ne peut avoir qu'un seul attribut de type ID
- un attribut ID peut être optionnel (#IMPLIED) ou obligatoire (#REQUIRED)
Syntaxe
2 <!ELEMENT e (...)> <!ATTLIST e
3 a ID #REQUIRED>
Définition : Réference à des éléments identifiés (IDREF)
Les attributs de type IDREF permettent de faire référence à un élément identifié, par la valeur de l'attribut ID correspondant. La valeur d'un attribut IDREF doit correspondre à la valeur d'un attribut ID dans le document (sinon le document n'est pas valide, principe d'intégrité référentielle).
Syntaxe
Remarque : IDREFS
Un attribut de type IDREFS permet de faire référence à plusieurs élément identifiés, le séparateur étant un espace (référence de cardinalité N:M).
Exemple : DTD avec ID, IDREF, IDREFS
<!ELEMENT e1 (e2 | e3 | e4)*> <!ELEMENT e2 (#PCDATA)> <!ELEMENT e3 (#PCDATA)> <!ELEMENT e4 (#PCDATA)> <!ATTLIST e2
id ID #REQUIRED> <!ATTLIST e3
ref IDREF #IMPLIED> <!ATTLIST e4
refs IDREFS #IMPLIED>
...
- Contenu mixte (mixed content)
Définition
On appelle mixed content (contenu mixte en français) un élément XML contenant à la fois du flux texte (#PCDATA) et des éléments fils.
On appelle élément inline un tel élément, au sens d'inclus dans le flux de caractères : "dans la ligne".
Déclaration de DTD dans les fichiers XML
Syntaxe
1 <!ELEMENT mixedElement (#PCDATA | inlineElement1 | inlineElement2 )*>
Remarque
#PCDATA doit être déclaré en premier dans la liste.
...
- Déclaration de DTD dans les fichiers XML
Syntaxe
L'instruction DOCTYPE situé en début de fichier XML (entre l'entête et la balise racine) permet d'associer un fichier XML à la DTD qui permet de la valider. Les parseurs validant pourront ainsi directement informer sur la validité du fichier.
Syntaxe : Déclaration de DTD privée
Une DTD privée est une DTD réalisée pour ses besoins propres (langage local).
1
avec :
rootElement le nom de l'élément racine
url est une URL décrivant le chemin de la DTD : en local sur un disque, en chemin absolu ou relatif par rapport à la position du fichier XML, ou sur Internet typiquement.
Exemple : Déclaration de DTD privées
Syntaxe : Déclaration de DTD publique
Une DTD publique est une DTD standard mise à disposition pour une communauté élargie.
1
avec :
- publicName est un nom public pour la DTD, qui permettra à un système informatique de rechercher en priorité la DTD via un catalogue local.
- url est une URL décrivant le chemin de la DTD comme pour le mode SYSTEM.
Exemple : Les DTD DITA et XHTML
…
….
- Exemple de DTD
Exemple : DTD (inspirée de DITA)
<!ELEMENT topic (title,body)> <!ATTLIST topic
id NMTOKEN #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT body (p)+> <!ELEMENT p (#PCDATA|term)*> <!ELEMENT term (#PCDATA)>
Exemple : Contenu valide par rapport à topic-litre.dtd
Topic title
This is un exemple of DITA topic.
...
- Inconvénients et avantages des DTD
Les DTD * présentent des inconvénients et des limites technologiques qui ont suscité le développement de certaines solutions concurrentes.
La syntaxe DTD en résumé
Le premier défaut des DTD * est qu'elles s'écrivent avec un langage spécifique, avec sa propre syntaxe, ce qui est d'autant plus déroutant que l'on traite avec un méta-langage (permettant de créer des langages !). On attendrait donc des DTD qu'elles s'expriment en XML.
De plus, avec l'essor du XML * et son utilisation conjointe avec d'autres applications (systèmes de base de données notamment), le couple XML+DTD ne fournissait pas une solution satisfaisante car :
- Il ne garantit pas que les éléments terminaux (#PCDATA) contiennent des données d'un certain type ou dans un format contrôlable
- Il ne permet pas dans le cas général d'exprimer exactement la cardinalité d'un élément (indiquer qu'un tableau doit contenir un nombre x de colonnes et y de lignes).
Exemple : Langages concurrents des DTD
- XML Schema (W3C)
- Relax NG (OASIS)
- Schematron
- Examplotron
- etc.
Attention : Quel utilisation des DTD ?
Les DTD restent aujourd'hui très utilisées, malgré leurs lacunes, pour leur simplicité et leur efficacité dans la description des langages de description documentaires.
Elles ne sont en revanche plus utilisées pour les langages orientés données, où on leur préfère largement les XML Schema par exemple.
Exemple : Une DTD standard
La DocBook (www.docbook.org) est une DTD posant les règles de structuration de livres techniques (en particulier dans le domaine de l'informatique) en chapitres, parties, etc
- La syntaxe DTD en résumé
La syntaxe des DTD repose sur un langage déclaratif, permettant de spécifier les éléments autorisés et pour chaque élément autorisé les fils qu'il peut contenir. Les aspects essentiels de la syntaxe sont présentés dans le tableau ci-dessous.
...
Types de données
Syntaxe
Ajouter l'attribut datatypeLibrary="…/2001/XMLSchema-datatypes" à la racine grammar.
4 ...
Définition : Types primitifs
- string
- boolean
- decimal
- float, double
- date, dateTime, duration, time, gYearMonth, gYear, gMonthDay, gDay, gMonth
- hexBinary, base64Binary
- anyURI
- QName, NOTATION
- Types hérités des DTD : ID, IDREF, IDREFS...
Complément : Spécification des primitive datatypes
…
Paramètre de spécialisation des types primitifs.
Exemple : Type string
Facettes :
- length : longueur de la chaîne
- pattern : expression régulière permettant de valider la chaîne par rapport au patron (définition en intention)
- enumeration : liste de valeurs autorisées (définition en extension)
-
...
Syntaxe : Element
1 element e1 { element e2 {...
Syntaxe : Attributs
1 element e2 { attribute a1 {...
Syntaxe : Nœuds texte
1 element e1 {text}
Syntaxe : Cardinalité
1 element e1 { element e2 {...}*, element e3 {...}+, ...}
Syntaxe : Optionalité
1 element e1 { element e2 {...}?, attribut a1 {...}?}
Syntaxe : Alternative
1 element e1 { element e2 {...} | element e3 {...}}
Exemple : Ensemble non ordonné (set)
1 element setElement { (element e2 {...} | element e3 {...})* }
Exemple : Contenu mixte (mixed-content)
1 element paraTag { (text | element inlineTag {text})* }
Syntaxe : Énumération
1 attribute a1 { "v1" | "v2" }
1 element e1 { "v1" | "v2" }
Syntaxe : Pattern nommés
2 ...
Syntaxe : Syntaxe générale
2 start = element e1 {...} Pattern1 = ...
- Complément : Principes de conception de schémas
Quelques exemple de principes d'écriture d'un schéma:
- "Poupées russes" : schéma arborescent dans lequel chaque élément est défini localement à son père
element e1 {element e2 {...}}
NB : Suit la structure des instances, pas de réutilisation de pattern
- "Tranches de salami" : schéma réseau dans lequel chaque élément est défini globalement element e1 {... E2 ...} / E2={...}
NB : pas de redéfinition de pattern
...
Exemples
- Exemple: Carnet d'adresse (XML, DTD, Relax NG)
Exemple : Instance XML
Exemple : DTD
John Smith
js@example <;/email>
Fred Bloggs
fb@example <;/email>
...
Exercices
- Exercices DTD
Rappel: Manipulation des Schémas XML (cf. p.) dans Oxygen
1.1. Exercice: Une DTD
Soit la DTD suivante:
<!ELEMENT entete titre date auteur motscles* resume
( , , +, , ?)>
<!ELEMENT titre #PCDATA
( )>
<!ELEMENT date #PCDATA
( )>
<!ELEMENT auteur #PCDATA
( )>
<!ELEMENT motscles #PCDATA
( )>
<!ELEMENT resume (paragraphe+)> <!ELEMENT paragraphe #PCDATA
( )>