Mémento XML – DTD – XPath

1	Syntaxe d'un document XML
1.1	En-tête
L'en-tête d'un document XML commence par une ligne comme suit :
<?xml version="1.0" encoding="iso-8859-1"?>
L'attribut encoding précise le jeu de caractères utilisé dans le document (ici, caractères de l'Europe de l'Ouest). D'autres valeurs peuvent être par exemple UTF-8 ou UTF-16 pour un codage Unicode.
L'attribut standalone est facultatif. La valeur yes signifie que le document n'est lié à aucune DTD. Si sa valeur est no, une ligne doit spécifier l'emplacement du fichier. Si la DTD se trouve sur la machine locale, cette ligne aura la forme suivante :
<!DOCTYPE nom_element_racine SYSTEM "fichier.dtd">
DOCTYPE et SYSTEM sont des mots réservés, nom_element_racine précise le nom de l'élément racine du document et fichier_dtd est le chemin d'accès au fichier DTD associé. Le chemin d'accès désigne un fichier local à la machine ou une URL.
La DTD peut également être accessible via internet. Dans ce cas, le mot-clé SYSTEM est remplacé par PUBLIC qui spécifie la localisation de la DTD via une URL :
<!DOCTYPE nom_element_racine			
			PUBLIC nom_dtd_quelconque
			"http://.../fichier.dtd">

Le nom de la DTD et peut être une chaîne de caractères quelconque.
1.2	Nom des éléments XML
Le nom d'un élément XML doit commencer par une lettre ou le caractère underscore _. Ce premier caractère peut être suivi de lettres, chiffres, et des caractères - _ :
Une balise ouvrante <balise> doir être fermée par </balise> et une balise vide doit être terminée par / : <balise_vide/>.
Il est d'usage de ne pas utiliser de caractères accentués, d'écrire les noms de balises et d'attributs en minuscules et d'utiliser comme séparateurs les caractères tiret - et underscore _
Il est préférable, à moins d'avoir une bonne raison, de ne pas utiliser le caractère "deux point" : qui a une signification particulière.
1.3	Attributs des éléments
Les balises ouvrantes et balises vides peuvent contenir des attributs écrits sous la forme nom="valeur" :
<element_xml nom_att1="val1" nom_att2="val2" ... nom_attn="valn">
	... texte ...
	<balise_vide nom_att1="val1" nom_att2="val2" ... nom_attn="valn"/>
	... texte ...
</element_xml>
1.4	Caractères
Entre deux balises, tous les caractères faisant partie du jeu mentionné dans l'attribut encoding de l'en-tête peuvent être utilisés, à l'exception de :
	< et >, utilisés pour délimités les balises. On utilise en remplacement les entités suivantes : &lt; et &gt; (pour less than et greater than)
	&, utilisé pour introduire les entités. Ce caractère est remplacé par &amp; (pour ampersand)

Un caractère ne faisant pas partie du jeu spécifié peut être remplacé par son code unicode sous la forme &#NNNN; en décimal ou &#xNNNN; Par exemple, &#x00BD; correspond au caractère 
Il est possible de ne pas remplacer les caractères spéciaux en utilisant, au sein d'un élément, une section "CDATA". La syntaxe est la suivante :
<element_xml>
	<![CDATA[[
		ici on peut utiliser les symboles <, > et &
	]]>
</element_xml>
Lors de l'analyse d'une telle section par un parseur XML, les caractères spéciaux ne seront pas interprétés.
1.5	Commentaires
Les délimiteurs de commentaires sont les mêmes qu'en HTML :
<!--	ceci est un commentaire entre ses deux délimiteurs	->
2	Syntaxe d'une DTD
Une DTD est un fichier au format texte, sans en-tête. Le fichier peut avoir un nom quelconque mais il est d'usage de le suffixer par ".dtd"
2.1	éléments
La définition d'un élément s'écrit :
<!ELEMENT nom_element (structure_element)>

La structure de l'élément peut être :
	- Une séquence (nom des éléments fils séparés par des virgules)
(element1, element2, ..., elementn)
Chaque élément mentionné dans une séquence peut-être suivi de sa cardinalité (nombre de fois ou il peut ou doit apparaître). Ne pas indiquer de cardinalité signifie que l'élément est obligatoire et ne doit appraître qu'une seule fois. Les symboles de cardinalité sont :

*	zéro ou plusieurs fois	
+	une ou plusieurs fois	
?	une fois au plus	
			
	- Un choix (noms des éléments fils séparés par le caractère | )
(element1 | element2 | ... | elementn)

	- Vide (balise sans contenu)
EMPTY

	- Du texte
#PCDATA

	- Mixte (texte et autres balises en ligne, vides ou non)
(#PCDATA | element1 | ... | elementn)*

2.2	Attributs
La définition des attributs éventuels d'un élément s'écrit :
<!ATTLIST nom_element
	nom_attribut1 TYPE (#REQUIRED ou #IMPLIED ou "valeur par défaut")
	nom_attribut2 TYPE (#REQUIRED ou #IMPLIED ou "valeur par défaut")
...>

Les principaux types des attributs sont les suivants :

CDATA	texte	
(val1 | val2 | ... | valn)	une des valeurs énumérées	
ID	valeur unique (une valeur donnée ne peut appraître qu'une seule fois dans le document pour cet attribut)	

Les mots-clés #REQUIRED et #IMPLIED signifient respectivement que l'attribut est obligatoire ou facultatif. 
Dans le cas d'un attribut "énumération" facultatif, on peut préciser sa valeur par défaut (i.e. valeur prise implicitement lorsqu'aucune valeur n'est spécifiée).

3	XPath
XPath désigne la syntaxe utlisée pour adresser des éléments particuliers d'un document XML en fonction de leur structure et/ou de leur contenu.

3.1	Filiation
La sélection relative à la structure utilise une syntaxe similaire aux systèmes de fichiers Unix. Deux caractères spéciaux sont utilisés :
	- / permet de séparer les éléments de manière hiérarchique (père/fils). Utilisé en début d'expression, ce caractère représente la racine du document ;
	- .. désigne la parent de l'élément courant
	- * représente un élément de nom quelconque.

/	racine du document	<r>
    ...
</r>	
/r	Racine du document. Le nom de la racine est r	<r>
    ...
</r>	
/r/f	élément f, fils de la racine r	<r>
    <f>...</f>
</r>	
//e	élément e, où qu'il se trouve	<...>
    ...
       <e> ... </e> 
    ...
</...>	
//e/f	élément fils d'un élément e, où que se trouve l'élément e	<...>
    ...
       <e>
          <f> ... </f> 
       </e> 
    ...
</...>	
//e/*	tout élément fils d'un élément e	<...>
    ...
       <e>
          <...> ... </...> 
       </e> 
    ...
</...>	
//e//*	tout descendant d'un quelconque élément e	<...>
    ...
       <e>
          ...
          <...> ... </...> 
          ...
       </e> 
    ...
</...>	
//e/@attr	attribut attr d'un élément e	<...>
  ...
   <e truc="..." attr="valeur">...</e> 
  ...
</...>	
//e[@attr="val"]/../f	tous les éléments f frères de (tout élément e possédant un attribut attr de valeur val)	 ...
   <p>
      <e truc="..." attr="val">...</e>
       <f> ... </f>
       <x> ... </x>
       <f> ... </f>
   </p>
 ...	

3.2	Clauses sur les éléments et les attributs
On peut restreindre la sélection des éléments à l'aide d'expressions placées entre crochets à la suite du nom des éléments :
//nom_element[contraintes]
On peut combiner plusieurs contraintes avec les opérateurs logiques and, or et ! (not). Les contraintes peuvent porter sur la valeur textuelle ou numérique des éléments fils ou sur celles des attributs (dont le nom est précédé par le symbole @). La sémantique des opérateurs utilisés est parfois interprétée implicitement en fonction du contexte. Par exemple, l'opérateur > (supérieur) fera référence à l'ordre arithmétique si les éléments comparés représentent des nombres, à l'ordre lexicographique en présence de chaînes de caractères.
Un certain nombre de fonctions et opérateurs sont également mis à disposition. Nous pouvons en cite quelques-uns :
	
contains(string1, string2)	Sélectionne l'élément courant si string1 contient la sous-chaîne string2. Cette fonction est sensible à la casse.	
starts-with(string1, string2)	Sélectionne l'élément courant si string1 commence par string2	
string-length(string)	renvoie la longueur de la chaîne string	
position()	position de l'élément courant (position par rapport à l'élément père, dans la liste des fils)	
text()	Désigne l'ensemble des éléments textes fils de l'élément courant	
div	x div y renvoie le résultat de la division réelle de x par y	
mod	x mod y renvoie le résultat de la division réelle de x par y	
<, >, <=, >=, =, !=	supérieur, inférieur, inférieur ou égal, supérieur ou égal, égal, différent	
.........		

La liste exhausitve se trouve sur http://www.w3.org/TR/xpath

à propos de text()

Dans le cas du document suivant :
<date>
	<jour>9</jour>
	<mois>juin</mois>
	<annee>2004</annee>
</date>

L'expression //date/text() évaluée dans oXygen provoque l'apparition du message "la requête XPath n'a renvoyé aucun résultat". 
Avec l'élément <date>9 juin 2004</date>, la même expression renvoie dans oXygen le texte "9 juin 2004".

Dans le cas d'un élément mixte :
<article categorie="Le Kiosque">
	<titre>Un rapport encombrant pour Tenet</titre>
	<corps>
		Selon le «<journal>New York Times</journal>», le patron de la CIA a démissionné avant la publication
            	d'un rapport du Sénat très gênant sur les activités de l'agence en Irak.
	</corps>
</article>

L'expression //corps/text() renvoie dans oXygen deux éléments :

Selon le «
et 
 le patron de la CIA a démissionné avant la publication d'un rapport du Sénat très gênant sur les activités de l'agence en Irak.

4	Exemple : courrier électronique
4.1	DTD
<?xml version="1.0" encoding="iso-8859-1"?>
<!ELEMENT email (expediteur, destinataires, sujet?, date, corps, signature?, ps?)>
<!ATTLIST email
		priorite (basse | normal | urgent) #REQUIRED
		categorie CDATA #IMPLIED>
<!ELEMENT expediteur (nom, adresse)>
<!ELEMENT destinataires (destinataire)+>
<!ELEMENT destinataire (nom, adresse)>
<!ELEMENT nom (#PCDATA)>
<!ELEMENT adresse (#PCDATA)>
<!ELEMENT sujet (#PCDATA)>
<!ELEMENT date (jour, heure)>
<!ELEMENT jour (#PCDATA)>
<!ELEMENT heure (#PCDATA)>
<!ELEMENT corps (#PCDATA)>
<!ELEMENT signature (#PCDATA)>
<!ELEMENT ps (#PCDATA)>

4.2	Exemple de fichier XML

<email priorite="urgent" categorie="enseignement">
	<expediteur>
		<nom>Ludovic Tanguy</nom>
		<adresse>tanguy@univ-tlse.fr</adresse>
	</expediteur>
	<destinataires>
		<destinataire>
			<nom>Franck Sajous</nom>
			<adresse>sajous@univ-tlse.fr</adresse>
		</destinataire>
		<destinataire>
			<nom>Syd Baret</nom>
			<adresse>baret.syd@laposte.net</adresse>
		</destinataire>
	</destinataires>
	<sujet>Tutoriel XML</sujet>
	<date>
		<jour>8 Juin 2004</jour>
		<heure>17h37</heure>
	</date>
	<corps>
		Bonjour,
		Trouvé un exemple de document XML ?
		Ludovic
	</corps>
	<signature>
		Ludovic Tanguy – ERSS / Dpt. Sciences du Langage
		T: 05 61 50 36 03 – F : 05 61 50 46 77
	</signature>
	<ps>Et des expressions XPath ?</ps>
</email>

4.3	Exemple d'expressions XPath
	
/email/@priorite	urgent	
//@priorite	urgent	
//nom	Ludovic Tanguy
Franck Sajous
Syd Baret	
//destinataires//nom	Franck Sajous
Syd Baret	
//destinataire[
    (contains(adresse, 'univ-tlse.fr') = false)
    and
    (starts-with(nom, 'Syd'))
]	<destinataire>
	<nom>Syd Baret</nom>			<adresse>baret.syd@laposte.net</adresse>
</destinataire>	
//destinataire[
    (contains(adresse, 'univ-tlse.fr') = false)
    and
    (starts-with(nom, 'Syd'))
]/adresse	baret.syd@laposte.net