• Aucun résultat trouvé

Représentation XPath d’un document XML

2.4 Le langage XPath

2.4.1 Représentation XPath d’un document XML

2.4.3 Les axes . . . 91 2.4.4 Les filtres . . . 98 2.4.5 Prédicats . . . 100 2.4.6 Types et opérations XPath . . . 103 2.4.7 Exemples d’expressions XPath . . . 107

Nous approfondissons dans ce chapitre la notion de document XML, en mettant l’accent sur la structure d’un document et sur la navigation dans cette structure. Ces deux aspects sont en effet à la base de la programmation XSLT.

Nous suivons la démarche adoptée dès l’introduction, consistant à considérer un document XML comme un arbre. Ce point de vue a le grand avantage d’être indépendant de l’origine du document et de faire abstraction de sa représentation physique ou textuelle : la représentation arborescente est conceptuelle et a pour but de décrire sans ambiguïté la structure et le contenu d’un document. Ce n’est pas le cas d’une représentation textuelle ou « sérialisée » où un même contenu peut être représenté avec des constructions syntaxiques différentes. Par exemple un élément vide a une seule représentation dans l’arborescence (un nœud sans fils) mais possède deux représentations textuelles équivalentes : " a#%" /a# et " a/# . Un autre exemple d’une tel ambiguïté est le caractère ’>’ qui peut-être représenté par ’>’ et ’>’ dans un document XML.

Nous décrirons la structure arborescente d’un document XML en nous appuyant sur un modèle normal- isé de représentation et de manipulation de données XML, le modèle DOM. Dans la suite, et quand il est nécessaire de distinguer explicitement les deux types de représentation, nous utiliserons le terme document sérialisé pour désigner la représentation textuelle d’un document XML et le terme arbre DOM pour sa représentation arborescente.

Avant d’être transmis à un traitement, quel qu’il soit, un document XML (sérialisé) est traité par un processeur XML ou parseur qui va analyser son contenu et déterminer sa structure. Dans le cas d’un parseur DOM le résultat de cet analyse est un arbre DOM. Dans tous les cas, cette phase d’analyse peut échouer si le document n’est pas bien formé, autrement dit s’il ne respecte pas la syntaxe du langage XML. Bien que cette syntaxe ne soit pas nécessaire pour expliquer le fonctionnement de XSLT proprement dit, il est important de bien comprendre comment un document XML est transformé en arborescence DOM et inversement.

Nous utiliserons également le modèle DOM (Document Object Model) pour compléter notre descrip- tion de la structure d’un document par les opérations de navigation dans ce document. DOM fournit une spécification orientée-objet basée sur des méthodes d’investigation et d’extraction de données. Bien que cette spécification définisse de manière précise les opérations sur un arbre XML, sa mise en œuvre en pra- tique nécessite le recours à un environnement de programmation comme Java. Le langage XPath, étudié dans la seconde partie de ce chapitre, offre un outil plus simple pour déclarer des chemins complexes d’accès à des éléments. C’est XPath qui est utilisé dans XSLT, et pas les opérations DOM, mais il est important de signaler dès maintenant que l’évaluation d’un programme XSLT peut être décrite en DOM (même si le système lui-même n’utilise pas nécessairement cette API), et que la compréhension de ce modèle donne donc la clé d’une bonne interprétation des règles XSLT.

2.1

La syntaxe XML

Les documents XML sont la plupart du temps créés, stockés ou échangés sous une représentation textuelle ou sérialisée qui « marque » la structure par des formes syntaxiques (essentiellement des balises) mêlées au contenu textuel. Nous donnons maintenant les règles syntaxiques de base pour représenter des documents XML sérialisés. Nous verrons dans la section suivante comment on passe de cette représentation à une représentation arborescente sous forme d’un arbre DOM.

Commençons par l’exemple d’un document XML dont le contenu – sommaire – résume les principaux aspects syntaxiques du langage.

Exemple 21 ExXML4.xml : Illustration de la syntaxe XML

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <!DOCTYPE A SYSTEM "minimal.dtd" [

<!ENTITY monTexte "texte simple">

<!ENTITY maSignature SYSTEM "signature.xml"> ]>

<!-- Instruction de traitement -->

2.1. LA SYNTAXE XML 57

<A>

Du &monTexte;, sans caractères réservés: ni &lt; ni &gt; ni &amp; ni &apos; ni &quot; <B> contenu texte </B> <!-- Un élément vide --> <C/> <D attr1="1" attr2="azerty"> <B>Encore &monTexte;,</B> </D>

<![CDATA[Du texte <non interprété> &monTexte;]]> &maSignature;

</A>

Cet exemple va nous servir de support à la présentation des différents composants d’un document XML.

2.1.1

Déclaration XML

La déclaration XML est une balise spéciale qui doit apparaître au début du document. Sa forme minimale indique la version de la norme XML à laquelle se conforme le document :

<?xml version="1.0"?>

Cette information est principalement destinée au traitement qui va analyser le document, afin qu’il puisse tenir compte des éventuelles variantes de syntaxe entre les différentes versions XML. On peut aussi lui associer des attributs (voir plus loin) caractérisant le document. Nous utilisons par exemple systéma- tiquement l’attributencodingavec la valeurISO-8859-1qui indique un codage de caractères « latin » incluant les caractères accentués.

L’attribut (optionnel)standaloneindique si le document XML contient des références vers d’autres fichiers ou « entités externes » (voir plus loin) qui doivent être chargées pendant l’analyse du document. La valeuryespermet au processeur XML de savoir qu’il n’est pas nécessaire d’accéder à d’autres sources pour analyser et restituer le document XML en entier. Dans notre exemple nous avons défini stan- dalone=’no’(qui est aussi la valeur par défaut) car, comme nous allons le voir maintenant, il contient une référence vers une entité externe.

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>

La déclaration de document est uniquement destinée au parseur, et n’est plus « visible » dans l’arborescence DOM d’un document XML. On ne peut donc y avoir accès dans un traitement XSLT.

Contrainte : La déclaration XML est optionnelle, mais sa présence est cependant recommandée. Si elle est présente, elle doit être la première ligne du document.

2.1.2

Déclaration du type de document et des entités

La balise spéciale" !DOCTYPE# définit la DTD (Définition du Type de Document) qui est une description générale de la structure du document. Cette description peut être entièrement incluse dans la balise sous forme de déclarations locales, mais le plus souvent on fait appel à une source externe (ce peut être un nom de fichier local, ou une URL). La forme générale de la déclaration est alors :

" !DOCTYPE nomDocument SYSTEM "sourceExt" [decLoc]#

Cette déclaration indique tout d’abord que le document est de typenomDocument. Après le mot-clé SYSTEMon trouve l’URLsourceExtqui correspond à un fichier avec des déclarations externes sur la structure du document. Les déclarations localesdecLocsont entourées des symboles[et].

Un problème bien connu des URL pour identifier des unités d’informations comme une page HTML ou un fichier DTD est l’utilisation d’un mécanisme d’adressage physique. Ce type d’adressage est risqué dans un environnement évolutif où les serveurs Web changent d’adresse et où les fichiers sont déplacés d’un

répertoire à l’autre. Pour remédier à ce problème, XML propose également l’utilisation « d’identificateurs publics », qui seront décrits dans le chapitre 4.

Les entités fournissent un moyen de factoriser des fragments XML et des réutiliser en plusieurs en- droits. Dans notre exemple, les déclarations d’entités sont locales (comprises entre les crochets [ ]) mais il peuvent également faire partie du fichier externesourceDTD. Notre document ExXML4.xml, page 56, contient la déclaration d’une entité interne (une simple chaîne de caractères) et d’une entité externe (un fichier) :

<!ENTITY monTexte "texte simple">

<!ENTITY maSignature SYSTEM "signature.xml">

Le nom de la première entité estmonTexteet sa valeurtexte simple. La deuxième entité a le nommaSignatureet sa valeur est définie par le contenu du fichiersignature.xml. Les deux entités peuvent ensuite être référencées dans le document par leur nom.

Contrainte : La déclaration du type de document est optionnelle. Si elle est présente, elle doit apparaître avant le premier élément du document.

2.1.3

Commentaires

Un commentaire est une zone de texte libre encadrée par " !--et--# . Il peut contenir n’importe quel texte, à l’exception de--, selon n’importe quelle disposition (sauts de lignes par exemple). Le commen- taire suivant est syntaxiquement correct (bien formé) :

<!-- Instruction de traitement <?xml-stylesheet ...> --> Les deux commentaires suivants ne sont pas corrects :

<!-- erreur: -- n’est pas permis --> <!-- erreur: --->

Le deuxième commentaire n’est pas bien formé, car un commentaire ne doit pas terminer par «--->». Contrainte : Les commentaires peuvent être placés n’importe où dans le document, sauf dans une balise.

2.1.4

Instructions de traitement

Les instructions de traitement (processing instructions) sont conçues pour intégrer des instructions propres à un processeur particulier dans un document XML. Toute instruction apparaît dans une balise de la forme " ?nomInstruction attributs# . Nous utiliserons par exemple très souvent l’instruction suivante qui indique à un processeur XSLT l’adresse du fichier qui contient le programme pour la transformation du document :

<?xml-stylesheet href="prog.xslt" type="text/xslt">

Le mot qui suit le « ? » est la cible (target), le reste constituant le contenu de l’instruction de traitement. Il faut noter que la déclaration de document XML, bien que conforme à la définition syntaxique, n’est pas une instruction de traitement. De plus, le nom de cible ’xml’ (en minuscule, majuscule ou mélangé) est réservé pour des versions futures du standard XML.

Contrainte : Les instructions de traitement peuvent être placés n’importe où dans le document, sauf dans une balise.

2.1. LA SYNTAXE XML 59

2.1.5

Éléments

Les éléments constituent le principal composant d’un document XML. La représentation sérialisée de tout élément se compose d’une balise ouvrante " balise# , de son contenu et d’une balise fermante " /balise# . La présence des balises ouvrantes et fermantes est obligatoire. En revanche le contenu d’un élément peut être vide. Il existe alors une convention qui permet d’abréger la notation. L’élément vide

<C></C>

peut être noté

<C/>

Le contenu d’un élément peut aussi – et surtout – être constitué d’une combinaison arbitrairement complexe de commentaires, d’autres éléments, de références entités et de sections de texte (voir plus loin). Par exemple, le contenu de l’élément de typeAdans le fichier ExXML4.xml est une telle combinaison de catégories syntaxiques.

Contrainte : Tout document comprend un et un seul élément racine qui définit le contenu même du doc- ument.

Notre exemple ExXML4.xml contient un élément racine de typeA. Le document suivant n’est pas bien formé car il a deux éléments racine.

<?xml version="1.0"?> <A>Un premier contenu</A> <B>Un deuxième contenu</B>

Contrainte : Le nom du type de l’élément racine doit être identique au nom du type de document (si celui-i est présent).

Le document suivant n’est pas bien formé car le type de l’élément ne correspond pas au type du docu- ment :

<?xml version="1.0"?>

<!DOCTYPE A SYSTEM "fichier.dtd"> <B>contenu</B>

Le nom d’une balise, qui correspond au type de l’élément (voir plus loin), peut comprendre des lettres de l’alphabet, des chiffres, les caractères « - », « _ », mais pas de blanc ni de lettres accentuées. De plus le nom ne doit pas commencer par un chiffre. Enfin XML distingue les majuscules des minuscules, et la balise " NOM# sera donc considérée comme distincte de la balise " nom# (ces deux balises définissent deux éléments de types différents). Sous réserve de ces quelques restrictions, les noms d’élément sont libres en XML : il n’existe pas de nom réservé.

2.1.6

Attributs

Un élément peut avoir des attributs. Les attributs apparaissent toujours dans la balise ouvrante, sous la formenom="valeur"ounom=’valeur’, séparés par un espace blanc (voir plus loin). Les noms d’attributs suivent les mêmes règles que les noms d’éléments.

Contrainte : La balise ouvrante d’un élément ne doit pas contenir deux attributs avec le même nom. Par exemple le fragment XML suivant n’est pas bien formé :

Pour ceux qui auraient l’habitude des pratiques assez laxistes de HTML, il est bon de noter que

!

un attribut doit toujours avoir une valeur, donc la balise HTML" OPTION SELECTED# n’est pas du XML bien formé ;

!

la valeur doit toujours être comprise entre des apostrophes simples (’10’) ou des guillemets ("10") ; la valeur elle-même peut contenir des apostrophes simples si elle est encadrée par des guillemets, et réciproquement ;

Une caractéristique essentielle de XML est que l’ordre des attributs d’un élément n’est pas significatif. L’élément :

<A at1=’1’ at2=’2’/>

est donc identique à :

<A at2=’2’ at1=’1’/>

Autrement dit tout traitement doit donner le même résultat, indépendamment de l’ordre des attributs. En pratique il faudra toujours accéder à un attribut par son nom, et pas par sa position.

Il existe plusieurs noms d’attribut réservés dans XML (tous commencent par le préfixexml:) :

!

xml:lang: cet attribut permet d’indiquer la langue utilisée dans le contenu d’un élément. Les codes utilisés pour les langues sont définis par le standard IETF RFC 1766. Par exemple, les codes en,fretdeindiquent respectivement des contenus en Anglais, Français et Allemand.

!

xml:space: cet attribut précise le traitement des espaces dans le contenu d’un élément. Il a deux valeurs possibles, default ou preserved. Dans le premier cas, c’est l’application qui détermine le traitement des espaces. Dans le second cas, tous les espaces doivent être préservés par l’application.

!

le nom d’attributxmlnset tous les noms qui commencent parxmlns: sont également réservés pour la spécification d’espaces de nom.

Remarque : Les espaces de nom (namespace) constituent un aspect important de XML : ils seront décrits de manière approfondie dans le chapitre 6.

2.1.7

Espaces

Les espaces jouent un rôle spécial dans la représentation syntaxique d’un document XML. Un « espace » est une chaîne de caractères composée uniquement de caractères espace blanc (Unicode #x20), retour chariot (Unicode #x9), line feed (Unicode #xD) et tabulation (Unicode #xA) (voir page 64 pour plus de détails sur le standard Unicode).

Généralement les espaces blancs servent comme séparateurs entre les différents composants syntax- iques d’un document sérialisé. Par exemple, le fichier ExXML4.xml contient 18 lignes, c’est à dire 18 retours chariot. On voit également que, pour augmenter la lisibilité, le même document contient des es- paces (#x20) pour souligner la structure hiérarchique du document.

À priori un parseur XML doit transmettre tous les espaces à l’application exploitant le document (par exemple au processeur XSLT). Néanmoins, un programme XSLT permet de spécifier une prise en compte spécifique des nombreux espaces apparaissant dans un document XML. Il est courant par exemple d’ignorer tous les espaces en dehors de l’élément racine d’un document ou des éléments qui contiennent uniquement un espace blanc. Il est surprenant de constater que la gestion des espaces constitue un point très délicat dans la manipulation de documents XML. Nous aurons donc souvent l’occasion de revenir sur le traitement des espaces et la la distinction entre espaces significatifs et non-significatifs.

2.1. LA SYNTAXE XML 61

2.1.8

SectionsCDATA

Il peut arriver que l’on souhaite placer dans un document du texte qui ne doit pas être analysé par le parseur. C’est le cas par exemple :

1. quand on veut inclure de code de programmation qui contient des caractères réservés dans XML : les ’" ’ et ’&’ abondent dans du code C ou C++ ;

2. quand le document XML est consacré lui-même à XML, avec des exemples de balises que l’on souhaite reproduire littéralement.

Les sections littéralesCDATAdéfinissent une zone qui n’est pas analysée par le parseur, et est donc transmise telle quelle au programme traitant le document XML (par exemple un programme XSLT). Notre petit exemple contient une sectionCDATA:

<![CDATA[Du texte <non interprété> &monTexte;]]>

Cette section est transmise littéralement, et correspond donc à

Du texte <non interprété> &monTexte;

Il est clair que le traitement de ce contenu mènerait à résoudre les références à l’entitémonTexte, et à tenter d’interpréter" non interprété# comme une balise, ce qui d’ailleurs échouerait car il ne s’agit pas d’un nom d’élément valide.

2.1.9

Références d’entités

Chaque référence à une entité doit se faire sous la forme&nom;oùnomest le nom de l’entité. En pratique, dans un programme XSLT on considère que le parseur du document a remplacé toutes les références aux entités par leur valeur. Par exemple, la référence

&monTexte;

dans le document ExXML4.xml est remplacée par sa valeur, et on obtient :

texte simple

Cela signifie que nous n’avons pas à nous soucier des entités dans nos programmes XSLT puisque ceux-ci travaillent sur la représentation du document obtenue à l’issue de la phase de parsing, et donc après résolution des références aux entités.

Remarque : Le remplacement des références vers les entités par leur valeur n’est pas une obligation im- posée par la recommandation XML. L’avantage d’un tel remplacement est une programmation plus facile qui n’est pas obligée de se préoccuper de la composition physique d’un document XML.

La syntaxe XML permet de spécifier des caractères par leur code Unicode. Ainsi, au lieu d’écrireC en majuscule, on peut également utiliser la référence&#67;où l’entier 67 correspond à l’Unicode de ce caractère. Ce mécanisme de référencement est utile pour inclure des caractères qui ne se trouvent pas sur le clavier qu’on utilise. Par exemple, le caractère « c

&

» dont le code est soit 169, soitxA9en hexadécimal (')(+*'-,+.0/213'),4/ , le symbole « x » après ’#’ indiquant que le code est en hexadécimal) peut être inclus dans un document XML par des références vers des entités caractères#169;ou#xA9;.

Mais les références vers les entités caractères sont surtout utiles pour inclure des caractères avec une signification spécifique dans la syntaxe XML : «<», «>», «&», «’» et «"». Par exemple, pour inclure le symbole «<» dans le texte sans qu’il soit interprété par le processeur XML comme le début d’une balise on peut utiliser la référence&#60;.

À priori, toutes les entités référencés dans un document XML doivent être déclarées dans sa DTD. Il existe deux exceptions : les entités caractères et les entités du tableau 2.1 si le document n’a pas de DTD :

Déclaration entité (prédéfinie) Référence Caractère <!ENTITY lt "&#60;"> &lt; <

<!ENTITY gt "&#62;"> &gt; > <!ENTITY amp "&#38;"> &amp; & <!ENTITY apos "&#39;"> &apos; ’ <!ENTITY quot "&#34;"> &quot "

Table 2.1: Entités caractères prédéfinies dans un document XML sans DTD

Du &monTexte; , sans caractères réservés: ni &lt; ni &gt; ni &amp; ni &apos; ni &quot;

Ce qui donnera, après résolution des références aux entités le texte suivant :

Du texte simple, sans caractères réservés: ni < ni > ni & ni ’ ni "

Les entités externes permettent quant à elles d’inclure le contenu d’un fichier.

<!ENTITY maSignature SYSTEM "signature.xml">

On peut donc insérer le contenu de signature.xml par une simple référence&maSignature;. Ce mé- canisme permet de constituer un document par assemblage de plusieurs autres, éventuellement accessibles sur le réseau. Par défaut, on suppose que le fichier inclus se trouve au « même endroit » que le document principal, mais il est également possible de définir un chemin d’accès différent à travers une URL absolue. XML distingue entre deux types d’entités externes : les entités XML (parsed entities) et les entités non-XML (unparsed entities) :

!

Une entité XML doit être conforme à la définition du contenu d’un élément. Ainsi une entité externe peut être un document XML bien-formé mais aussi un fragment XML avec plusieurs (ou sans) élé-