Notes de cours XML
XML
XML (eXtensible Markup
Language) est un standard du W3C. Il s'agit d'un format de
documents permettant de représenter des données sous
forme de texte, tout en conservant une certaine organisation. Le
modèle de données sous-jacent est un arbre (voir la
section 1.1). Il existe cependant
des extensions à XML permettant de considérer des
graphes.
Lorsque l'on considère XML, c'est souvent en conjonction avec
un ensemble de technologies qui vont permettre de l'utiliser. Voici
une partie de ces technologies:
- Descriptions de la forme des documents, par
exemple:
- Désignation / sélection de parties
de documents: XPath,
voir aussi la section 2.
- Liens inter et intra documents:
- XLink est un standard permettant
de créer des liens entre documents XML.
- XPointer permet au
contraire de créer des liens à internes à un
document.
- Transformation et interrogation de documents
XML:
- XSLT est un langage de
transformation de documents XML.
- XQuery est un langage
d'interrogation de documents XML. Il est abordé dans la
section 3.
- APIs standard pour lire des documents XML:
- DOM
permet de lire un document XML et de le manipuler sous sa forme
d'arbre.
- SAX
permet de parcourir un document XML en utilisant un système
basé sur un ensemble d'événements.
Modèle de données XML
Un document XML correspond à un ensemble de données organisées
dans un arbre. Cet arbre possède différents
types de noeuds:
La racine C'est le document dans son entier. Elle possède en particulier un
enfant spécifique correspondant au contenu du document. Ses autres enfants correspondent à des déclarations concernant ce document. Par exemple, il peut s'agir de commandes indiquant une
feuille de style XSLT.
Élément C'est un noeud possédant un nom. Ce nom peut être un nom simple, qui commence par une lettre et se continue par une série de lettres, de chiffres, de '
-
', '
_
', etc (voir la
spécification de XML). Il peut aussi avoir un préfixe, appelé
namespace. Il possède le plus souvent un ensemble de fils qui peuvent être de n'importe quel type (sauf la racine). Les fils qui sont des attributs sont considérés séparément des autres fils et sont non ordonnés. De plus il y a au maximum un attribut ayant un nom donné par élément. Les autres fils sont ordonnés et considérés au même niveau, qu'il s'agisse de texte, d'éléments, ou autre.
Attribut C'est un noeud qui associe un nom à une valeur. On ne peut trouver ces noeuds que comme enfants d'éléments.
Texte Du texte simple.
Commentaire Les commentaires sont considérés comme des noeuds à part entière dans l'arbre
XML.
Commande Ou processing instructions. Ce sont des instructions destinées à l'application qui va traiter le document. Il peut par exemple s'agir d'une feuille de style à utiliser lorsque le document est à présenter sous forme d'une page web.
Exemple
noeuds texte en rouge
attributs en vert
éléments en bleu
Syntaxe de XML
La syntaxe de XML
est basée sur des balises tout comme HTML, ou encore SGML qui est leur ancêtre commun.
Déclarations préliminaires
Un fichier XML débute par une série de déclarations optionnelles qui sont suivies
d'un élément qui correspond au contenu du document. Parmi les déclarations possibles,
deux sont fréquentes:
Le prologue
Il prend la forme d'une commande et permet de fournir un ensemble d'informations sur le document.
<?xml info1="val1" info2="val2" ... ?>
Parmi ces informations, on trouve la version de XML utilisée
(version
) et qui est presque toujours 1.0
,
l'encodage des caractères (encoding
) ou encore le
fait que le document fasse ou non référence à
d'autres documents (standalone
).
Exemple
Le prologue suivant:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
signifie qu'il s'agit d'un document XML version 1.0, que
l'encodage des caractères suit la norme unicode sur 8bits
(UTF-8) et que le document fait référence à d'autres
documents.
Une déclaration de type
Elle est de forme suivante:
<!DOCTYPE le-type [
déclarations supplémentaires ] >
où le-type
est au choix:
nom
-
nom PUBLIC identifiant
nom indique le nom
de l'élément principal du document, URL indique
l'url où peut être trouvée la DTD du document et
identifiant indique un identifiant publique pour le type,
tel que "-//W3C//DTD XHTML 1.0 Transitional//EN"
pour le
xhtml en version 1.0 transitionnelle.
Les déclarations supplémentaires correspondent
soit à la DTD complète, soit à des déclarations
qui s'ajoutent à la DTD.
Exemple La déclaration suivante:
<!DOCTYPE collection SYSTEM "collection.dtd"
[
<!ENTITY Arl "Arleston">
]>
indique que l'élément principal est nommé
collection
, que la description du document est donnée
dans le fichier collection.dtd
et que l'entité
Arl
correspond au texte Arleston
.
Syntaxe des noeuds de l'arbre XML
Attributs
Un attribut s'écrit
nom="valeur"
ou bien
nom='valeur'
Il doit
obligatoirement être placé à l'intérieur de la
balise ouvrante de l'élément qui est son père.
Éléments
La syntaxe d'un élément est la
suivante:
<nom attributs>... enfants qui ne sont pas des attributs ...</nom>
Les attributs d'un élément sont
séparés par des espaces. nom est le nom de
l'élément.
Un élément sans enfants autres que des attributs peut
s'écrire:
<nom attributs/>
Texte
Les noeuds texte sont écrits tels
quels, sauf en ce qui concerne les caractères spéciaux:
Caractère |
Comment l'écrire |
< |
< |
> |
> |
" |
"e; |
' |
' |
& |
& |
Il est également possible d'avoir recours aux sections
<tt>CDATA</tt> dont le contenu sera directement
interprété comme du texte brut, sans qu'il y ait besoin
d'échapper les caractères spéciaux. Leur syntaxe est
la suivante:
<![CDATA[contenu brut, sans
échappement]]>
Les commentaires s'écrivent:
<!-- le commentaire
-->
Les commandes (ou //processing instructions//)
Elles s'écrivent:
<?commande arg1="val1" arg2="val2" ... ?>
Exemple
Document XML correspondant à
l'exemple d'arbre XML précédent.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE collection SYSTEM "collection.dtd">
<collection>
<serie nom="Lanfeust de Troy">
<tome numero="1">
<scenariste>Arleston</scenariste>
<dessinateur>Tarquin</dessinateur>
<titre>L'ivoire du Magohamoth</titre>
</tome>
<tome numero="2">
<dessinateur>Tarquin</dessinateur>
<titre><![CDATA[Thanos l'incongru]]></titre>
</tome>
<editeur nom="Soleil"/>
</serie>
<serie nom="Calvin & Hobbes">
<tome numero="1">
<titre>Adieu, monde cruel</titre>
</tome>
</serie>
</collection>
DTDs
DTD signifie Document
Type Definition. Une DTD est une spécification de la
structure du document XML. Elle spécifie, pour chaque
élément du document, quels peuvent être ses enfants
et dans quel ordre ils peuvent apparaître. La DTD d'un
document peut être spécifiée soit dans le document
lui-même, à l'intérieur des crochets [ ] de la
déclaration <!DOCTYPE
...>, soit de manière externe grâce
aux définitions SYSTEM ou
PUBLIC de <!DOCTYPE
... > (voir la section 1.2.1). Une DTD peut également contenir
des définitions d'entités, qui permettent de définir
un alias pour un morceau de document XML.
- Déclarations <!ELEMENT
- Ces déclarations permettent de
spécifier le contenu d'un élément, c'est-à-dire
quels éléments peuvent apparaître comme enfants de
cet élément. Elle permet également de spécifier
si l'élément peut contenir du texte. Il est important de
noter que ces déclarations ne concernent pas les
attributs.
La syntaxe de ces déclarations est <!ELEMENT nom contenu>.
contenu peut être au choix:
- EMPTY: signifie
que l'élément ne peut avoir d'enfants.
- ANY: signifie que
l'élément peut avoir n'importe quels enfants.
- ( #PCDATA | nom1
| nom2 ... )* signifie que l'élément peut
avoir comme enfants une alternance de texte et d'éléments
nom1, nom2, etc, sans restriction sur le nombre
ou l'ordre de ces éléments. On appelle un tel contenu
mixed content. C'est par exemple le type de contenu
utilisé pour de nombreux éléments en XHTML, tels que
div ou p.
- Une expression régulière de la
forme:
- nom: un
élément nom
- #PCDATA: du
texte
- r1 ,
r2: concaténation
- r1 |
r2: choix
- (r1)+: au
moins une fois
- (r1)*:
zéro, une ou plusieurs fois
- (r1)?:
zéro ou une fois
dans lesquelles r1 et r2 sont des expressions
régulières et nom est le nom d'un
élément.
Exemple 5
<!ELEMENT collection
(serie)*>
signifie que l'élément collection ne peut
avoir comme enfants que des éléments serie en
nombre quelconque.
<!ELEMENT tome
(scenariste?,dessinateur?,titre)>
signifie que l'élément tome a comme enfants
éventuellement un élément scenariste,
ensuite éventuellement un élément
dessinateur et enfin exactement un élément
titre.
- Déclarations
<!ATTLIST >
Ces déclarations permettent de spécifier les attributs
qui peuvent apparaître dans un élément.
La syntaxe de ces déclaration est:
<!ATTLIST nom declarations
d'attributs>
où nom est le nom de l'élément
considéré et déclarations d'attributs est
une suite de déclarations de la forme:
- nom_att type
"valeur": si l'attribut nom_att
apparaît, sa valeur doit être du type type. Si
l'attribut nom_att n'apparaît pas, il est
intégré automatiquement dans l'arbre avec la valeur
valeur (i.e. valeur est sa valeur par
défaut). Si cette valeur par défaut est
précédée de la mention #FIXED, alors c'est la seule valeur autorisée
pour cet attribut.
- nom_att type
#REQUIRED: l'attribut nom_att doit apparaître
et sa valeur doit être de type type.
- nom_att type
#IMPLIED: l'attribut nom_att est optionnel. S'il
apparaît, sa valeur doit être de type type.
Parmi les types existants, on peut avoir les types suivants:
- CDATA: du
texte
- (val1|val2|...):
val1, val2, etc sont les seules valeurs
autorisées pour cet attribut.
- ID: un identifiant
pour cet élément. Il y a au maximum un attribut avec un
tel type par élément.
- IDREF (ou bien
IDREFS): un identifiant (ou dans le
second cas une suite d'identifiants) servant de référence
vers un autre élément.
Exemple 6
<!ATTLIST editeur nom CDATA #REQUIRED adresse CDATA #IMPLIED>
signifie que dans un élément editeur, on a
obligatoirement un attribut nom qui a comme valeur du
texte et éventuellement un attribut adresse qui a
également comme valeur du texte.
- Déclarations <!ENTITY >
Ces déclarations sont utilisées pour définir des
entités, c'est-à-dire un nom pour un morceau de XML. Ce
morceau peut être soit directement donné dans la
déclaration, soit être le contenu d'un fichier. Cette
dernière version permet ainsi d'inclure des fichiers dans le
document.
La syntaxe de la déclaration est l'une des trois suivantes:
- <!ENTITY nom
"valeur">: Lorsque l'entité
&nom; sera rencontrée dans le document, elle sera
remplacée par valeur. Il est important de noter que
valeur sera interprété comme du XML et non comme
du texte pur. En particulier les balises qui peuvent
apparaître dans valeur correspondront bien à des
éléments.
- <!ENTITY nom SYSTEM
"url">: Lorsque l'entité &nom;
sera rencontrée dans le document, elle sera remplacée par
le contenu du document indiqué par url.
- <!ENTITY nom PUBLIC
"identifiant_public" "url">: Lorsque
l'entité &nom; sera rencontrée dans le
document, elle sera remplacée par le contenu du document
indiqué par l'identifiant_public. Le document peut
être récupéré en utilisant url, mais
également par n'importe quel autre moyen qui correspondrait
à identifiant_public, comme par exemple l'utilisation
d'une copie locale du fichier.
Exemple 7
signifie que l'entité &Arl; sera
remplacée par le texte "Arleston".
<!ENTITY Tar "<dessinateur>Tarquin</dessinateur>">
signifie que l'entité &Tar; sera
remplacée par un élément dessinateur ayant
un enfant qui est un noeud texte ayant comme valeur
"Tarquin".
Exemple 8
Document XML avec DTD correspondant à l'exemple 1 d'arbre XML mais cette fois ci avec une DTD
définie dans le document lui-même. On peut noter que les
entités &Arl; et &Tar; qui sont
définies dans cette DTD sont utilisées dans le
document.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE collection
[
<!ELEMENT collection (serie*)>
<!ELEMENT serie (tome+,editeur?)>
<!ATTLIST serie nom CDATA #REQUIRED>
<!ELEMENT tome (scenariste?,dessinateur?,titre)>
<!ATTLIST tome numero CDATA #REQUIRED>
<!ELEMENT scenariste (#PCDATA)>
<!ELEMENT dessinateur (#PCDATA)>
<!ELEMENT titre (#PCDATA)>
<!ELEMENT editeur EMPTY>
<!ATTLIST editeur nom CDATA #REQUIRED adresse CDATA #IMPLIED>
<!ENTITY Arl "Arleston">
<!ENTITY Tar "<dessinateur>Tarquin</dessinateur>">
]
>
<collection>
<serie nom="Lanfeust de Troy">
<tome numero="1">
<scenariste>&Arl;</scenariste>
&Tar;
<titre>L'ivoire du Magohamoth</titre>
</tome>
<tome numero="2">
&Tar;
<titre><![CDATA[Thanos l'incongru]]></titre>
</tome>
<editeur nom="Soleil"/>
</serie>
<serie nom="Calvin & Hobbes">
<tome numero="1">
<titre>Adieu, monde cruel</titre>
</tome>
</serie>
</collection>
Un document XML est dit
valide si son contenu respecte les
déclarations de la DTD. Ainsi le document défini dans
l'exemple
8 est valide.
Espaces de nommage (Namespaces)
En programmation,
il arrive fréquemment que deux fonctions de deux
bibliothèques différentes portent le même nom. De
nombreux langages mettent à disposition du programmeur des
mécanismes permettant de lever l'ambiguïté qui en
résulte. On peut par exemple citer le système de modules
de Python ou encore le système de paquets en Java.
Ce problème de nommage peut également survenir en XML, en
particulier lorsque l'on cherche à manipuler plusieurs
documents simultanément. Par exemple, supposons que l'on
accède simultanément à un magasin de vente de livres
d'occasion et à une encyclopédie sur la littérature.
Supposons que l'on aie un élément annee pour les
livres vendus qui correspond à l'année d'impression du
livre et un élément annee dans
l'encyclopédie qui correspond à l'année de
première parution d'un livre. La signification de ces deux
éléments est différente et on aimerait pouvoir les
distinguer.
Les espaces de nommage (en anglais namespaces)
correspondent à des regroupement d'élément. Ils se
présentent sous la forme d'URIs, en général des
URLs. Le nom complet d'un élément est
composé de son espace de nommage et de son nom
local.
Exemple 9 Dans le cadre du magasin en ligne on peut
prendre comme espace de nommage l'URL du site internet du dit
magasin
ex: http://www.livres-pas-chers.com
De même on peut utiliser l'URL du site de
l'encyclopédie
ex: http://toutsurleslivres.org
Il se peut également qu'un nom ne soit dans aucun espace de
nommage auquel cas sont nom complet se résume à son nom
local. C'est le cas des documents que nous avons vu
jusqu'ici.
Déclarations des espaces de
nommage
Les espaces de nommage peuvent s'utiliser de deux manières:
soit en spécifiant un nom logique pour un espace de nommage,
soit en spécifiant un espace de nommage par défaut.
La spécification d'un espace de nommage par défaut se
fait en utilisant l'attribut spécial
xmlns. La valeur
de cet attribut est prise comme espace de nommage par défaut
pour l'élément de l'attribut, ainsi que pour tous ses
éléments descendants (mais pas pour les attributs).
Exemple 10
Dans le document
<livres xmlns="http://www.livres-pas-chers.com">
<livre>
<auteur>Stephen King</auteur>
<titre>Le fléau</titre>
<annee>2003</annee> <!-- ici c'est l'année d'édition !!! -->
<prix>5.3</prix>
</livre>
</livres>
tous les noms d'éléments sont dans l'espace de
nommage “http://www.livres-pas-chers.com”.
L'autre manière d'utiliser les espaces de nommage consiste
à leur associer un (ou même plusieurs) nom logique,
également appelé préfixe d'espace de nommage
(
namespace prefix). Ils se déclarent en utilisant un
attribut de la forme
xmlns:prefix, où
prefix est le préfixe que l'on souhaite
associer à l'espace de nommage. Comme pour le cas
précédent, la valeur de cet attribut spécifie
l'espace de nommage concerné. On peut ensuite spécifier
au coup par coup un espace de nommage pour un élément ou
un attribut en utilisant la notation
prefix:nom où
prefix est
un préfixe d'espace de nommage et où
nom est le
nom local de l'élément. Cette notation est appelée
nom qualifié (
qualified name). La portée de la
déclaration est l'élément, ainsi que ses
descendants.
Exemple 11
On reprend le document précédent et on l'enrichit
quelque peu:
<livres xmlns="http://www.livres-pas-chers.com">
<livre xmlns:encyclo="http://toutsurleslivres.org">
<auteur>Stephen King</auteur>
<titre>Le fléau</titre>
<annee>2003</annee> <!-- ici c'est l'année d'édition -->
<encyclo:annee>1978</encyclo:annee>
<!-- ici c'est l'année de première parution -->
<prix>5.3</prix>
</livre>
</livres>
tous les noms d'éléments sont dans l'espace de
nommage “http://www.livres-pas-chers.com”, sauf le
deuxième élément annee, qui, lui, est dans
l'espace de nommage
“http://toutsurleslivres.org”.
Afin de connaître l'espace de nommage associé à un
nom, on peut procéder comme suit:
- Si ce nom est un nom qualifié (i.e. de
la forme prefix:nom), alors l'espace de nommage
correspond à celui de prefix, et est donné par
xxx dans la déclaration de la forme
xmlns:prefix="xxx". En cas
d'ambiguïté, on prend la déclaration la plus proche
de l'élément considéré en remontant dans
l'arbre XML.
- Si ce nom est un nom local (sans
préfixe), alors l'espace de nommage est l'espace de nommage
par défaut, c'est à dire celui donné par
xxx dans la déclaration xmlns="xxx"
la plus proche en remontant dans l'arbre XML et en commençant
par le noeud courant. Si aucune déclaration de ce type
n'apparaît en remontant dans l'arbre XML, alors le nom n'est
associé à aucun espace de nommage.