• Aucun résultat trouvé

3.4 Évaluation d’un programme XSLT

4.1.2 Entités

Dans les chapitres précédents nous avons utilisé plusieurs fois des entités pour fragmenter physiquement le contenu sérialisé d’un document XML en plusieurs fichiers ou inclure des caractères spéciaux comme <,>,&,’et". D’une manière plus générale, la notion d’entité permet de déconnecter la définition logique d’un document XML sous forme d’arbre DOM de sa représentation physique sous forme de fichiers XML : un document XML peut ainsi être représenté par un ensemble d’entités très divers comme :

S

plusieurs fichiers XML, dites entités XML (parsed entities) ;

S

un fichier DTD optionnel ;

S

4.1. DÉFINITION DE TYPES DE DOCUMENTS : DTD 155 Parmi les entités XML, un fichier, appelé entité document, correspond à la racine du document XML et contient, directement ou indirectement, les références vers tous les autres entités. Chacune des entités XML peut contenir à son tour des références vers d’autres entités faisant partie du document (les entités non-XML ne peuvent pas contenir de telles références).

On obtient ainsi un graphe de référencement avec toutes les entités participant à la constitution du doc- ument XML (arbre DOM) final par un parseur. Cette constitution consiste essentiellement à remplacer les références vers les entités par leur contenu. Pour éviter des arbres DOM de taille infinie, ce graphe de référencement doit être acyclique : aucune entité ne doit se référencer elle-même directement ou indirecte- ment.

Pour pouvoir « utiliser » ou référencer une entité elle doit être définie au préalable dans la DTD du document. La seule exception à cette règle est la définition de la DTD elle-même, qui peut être stockée dans une entité DTD séparée et qui est définie et utilisée dans l’entité document avec la clause<!DOCTYPE ...>.

La définition d’une entité consiste à associer un contenu (XML ou autre) à un nom d’entité. XML distingue entre les entités internes dont le contenu est défini dans la DTD et les entités externes dont le contenu est un fichier séparé.

Une définition d’entité interne associe directement un nom à une valeur sans passer par une indirection à travers un fichier externe. Par exemple, l’entité suivante définit une entitéUcircavec comme valeur l’Unicode du symbole ’Û’.

<!ENTITY Ucirc "&#219;">

Dans la définition d’un entité externe, le nom de l’entité est associé à l’adresse d’un fichier (URL) qui définit son contenu. Voici les formes de définition d’entités externes :

<!ENTITY "nom_entité" SYSTEM "url_entity">

<!ENTITY "nom_entité" PUBLIC "id_publique" "url_entity">

La deuxième définition utilise un identificateur public en plus de l’URL de l’entité et permet une iden- tification plus formelle et surtout indépendante d’une adresse physique. Il est surtout appliqué à des docu- ments « publics » qui sont catalogués et largement référencés par d’autres documents.

Par exemple, la DTD XHTML définit une entité externe qui contient les définitions d’entités spécifiques à l’utilisation de caractères latin dans un document XML (le symbole%après la balise<!ENTITYindique qu’il s’agit d’une entité paramètre qui pourra être référencé dans la DTD même : voir plus bas).

<!ENTITY % HTMLlat1 PUBLIC

"-//W3C//ENTITIES Latin 1 for XHTML//EN" "xhtml-lat1.ent">

Dans le cas où l’URLxhtml-lat1.entest inaccessible, un parseur « intelligent » peut se servir de l’identificateur public pour trouver dans une liste d’URL (catalogue) une URL accessible (rien n’empêche d’ailleurs le parseur d’avoir une copie locale de cette DTD pour améliorer les performances).

Entités paramètres Comme pour un document XML, il est possible de découper une DTD en plusieurs entités (fichiers). Ces entités sont appelées des entités paramètres pour les distinguer des entités générales qui sont utilisées dans le contenu d’un document XML. La définition d’une entité paramètre est caractérisée par l’ajout du symbole%. Une référence vers une entité paramètre se compose du symbole%suivi par le nom de l’entité et terminé par le symbole;. Voici la définition et l’utilisation d’une entité paramètre externe dans la DTD XHTML :

<!ENTITY % HTMLlat1 PUBLIC

"-//W3C//ENTITIES Latin 1 for XHTML//EN" "xhtml-lat1.ent">

%HTMLlat1;

Les trois premières lignes définissent l’entité qui est référencée dans la quatrième ligne par son nom. Le résultat est l’inclusion de la DTD "xhtml-lat1.ent" - qui définit des entités pour les caractères latin - dans la DTD XHTML.

Entités non-XML et notations : Les entités non-XML comme les images et les fichiers son ont un statut très particulier dans le monde XML. En réalité, ce type d’entité est une boîte noire qui ne peut pas être analysée ou utilisée d’un manière « directe ». Pour pouvoir donner un minimum d’interprétation, XML permet la spécification de formats d’entités non-XML sous forme de déclarations de notations (nous avons mentionné dans la section consacrée à DOM page 64 l’existence d’une interface Notation) : une notation associe un nom de format à un identificateur système ou public qui pourra être exploité pour l’interprétation du contenu de l’entité. Généralement, cet identificateur définit une application qui peut se charger de l’affichage ou du traitement des entités non-XML de ce format.

Par exemple, la définition de format suivante associe le formatgifà une applicationxv: <!NOTATION gif SYSTEM ’/usr/local/bin/xv’ >

Attention, le nomgifest choisi librement et indépendant du format de l’entité.

Pour définir une entité non-XML du formatgif, on peut ensuite utiliser une syntaxe identique à celle de la définition d’entité externe, étendue par le mot réservéNDATA, suivi du nom du format :

<!ENTITY logo SYSTEM "image.gif" NDATA gif >

Une entité non-XML ne peut pas être référencée dans le contenu d’un document XML, qui est obli- gatoirement conforme à la syntaxe XML – ce qui ne serait très probablement plus le cas après l’inclusion d’une image GIF dans le contenu même. La seul possibilité de référencer des entités est de définir des attributs de typeENTITYouENTITIESqui peuvent ensuite prendre comme valeur un nom ou une liste de noms d’entités non-XML.

4.1.3

Éléments

Une DTD définit le vocabulaire et la grammaire d’un « dialecte » XML. Le vocabulaire est essentiellement constitué de noms d’éléments et d’attributs. La grammaire définit, pour chaque élément, ses fils et ses attributs possibles.

La définition générale d’un élément dans une DTD est la suivante : <!ELEMENT nom structure>

Contrainte : Il ne peut avoir qu’une seule définition pour chaque nom d’élément dans une DTD.

Prenons comme exemple la DTD XHTML qui décrit la dernière version de HTML (la version 4.0) comme un dialecte XML (voir page 165 pour une description complète). La DTD complète peut être téléchargée à l’URL http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd.

Voici la définition de l’élément racine d’un document HTML dans la DTD XHTML : <!ELEMENT html (head, body)>

Le mot réservé<!ELEMENTest suivi du nom de l’élément à définir (html). La structure de l’élément htmlest définie par(head, body).

Une DTD distingue cinq types de structures pour les éléments :

1. Si un élément est vide, on utilise le mot réservéEMPTYpour définir sa structure.

2. Si un élément ne peut contenir que du texte (des fils de type Text au sens DOM) on utilise le mot réservé#PCDATA. Par exemple, l’élémentT titleU de XHTML ne peut contenir que du texte : <!ELEMENT title (#PCDATA)>

3. Si élément ne peut contenir que des fils qui sont à leur tour des éléments, on spécifie les types des éléments fils possibles pour cet élément, le nombre d’occurences pour chaque fils et, éventuellement, l’ordre dans lequels ces fils doivent apparaître dans le document (rappelons qu’un document XML correspond à un arbre ordonné). Cette spécification est appelée le modèle de contenu de l’élément.

4.1. DÉFINITION DE TYPES DE DOCUMENTS : DTD 157 4. Si un type d’élément peut avoir un contenu « mélangé », c’est-à-dire contenir des fils qui sont des éléments mais également du texte, on spécifie les types des éléments qui peuvent être fils de cet élément. Dans ce cas, on ne peut plus spécifier le nombre d’occurences pour chaque fils ou l’ordre dans lequel ces fils doivent apparaître dans le document.

5. Il est également possible de ne définir aucune contrainte sur le contenu d’un élément en utilisant le mot réservéANY. Dans ce cas, le contenu de l’élément doit seulement être bien-formé, c’est-à-dire essentiellement respecter l’imbrication des balises.

Modèles de Contenu

Le modèle de contenu d’un élément indique les types de ses fils, mais également le nombre d’occurrences pour chaque type de fils. Si nécessaire, on peut également établir un ordre sur les occurrences des fils de chaque type.

La définition de la baliseT htmlU indique que l’élément racine de typehtmlne peut avoir que deux types d’éléments comme fils :headetbody. En plus, chaque type de fils ne doit apparaître qu’une seule fois et dans l’ordre indiqué. En d’autres termes, l’élément racine d’un document XHTML est toujours de la forme suivante :

<html>

<head>...</head> <body>....</body> </html>

Pour indiquer qu’un type d’élément peut apparaître zéro ou une fois on utilise le symbole?. Par exemple, la DTD suivante accepte les deux documents<A><C/></A>et<A><B/><C/></A>(BetC sont définis comme éléments vides) :

<!ELEMENT A (B?,C) > <!ELEMENT B EMPTY > <!ELEMENT C EMPTY >

Il existe également des symboles pour indiquer qu’un type d’élément peut apparaître plusieurs fois. On utilise le symbole*si un type de fils peut apparaître zéro, une ou plusieurs fois, et le symbole+s’il doit apparaître au moins une fois. Par exemple, si on remplace la définition précédente de l’élémentApar la définition :

<!ELEMENT A (B*,C+)>

la DTD accepte, entre autre, tous les éléments de typeAsuivants : <A><C/></A>

<A><C/><C/></A> <A><B/><C/></A> <A><B/><B/><C/></A>

En revanche, cette dernière définition n’accepte pas les éléments<A></A>et<A><C/><B/><C/></A>. Dans le premier cas, par définition, un élément vide T C/U doit apparaître au moins une fois, et dans le deuxième cas, tous les élémentsT B/U doivent apparaître avant tous les élémentsT C/U .

On peut donner le choix entre deux types d’éléments en remplaàant la virgule entre les éléments par le symbole|:

<!ELEMENT A (B|C)>

Dans ce cas,Apeut contenir un seul fils qui est soit de typeBou de typeC.

Finalement, on peut enlever la restriction sur l’ordre des fils : on voudrait par exemple accepter comme fils pour l’élémentT AU zéro ou plusieurs éléments de typeT BU etT CU dans n’importe quel ordre. Pour cela, on peut utiliser des parenthèses pour regrouper des éléments. La définition suivante indique que les éléments de typeAacceptent un élément de typeBou de typeCzéro ou plusieurs fois :

<!ELEMENT A (B|C)*>

Tous les éléments de typeAqui précèdent sont valides par rapport à cette définition, ainsi que les deux éléments suivants :

<A><C/><C/><B/><C/><B/></A> <A><B/><B/></A>

Ce parenthésage permet de définir des structures plus complexes. Par exemple, la structure d’un tableau HTML est définie par l’expression suivante (nous ne donnons pas la structure des éléments qu’il contient) : <!ELEMENT table

(caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>

S

les élémentscaption,theadettfootsont optionnels ;

S

l’élémentcaptionest suivi par zéro ou plusieurs éléments de typecoloucolgroup(il ne peut pas avoir simultanément les deux types d’éléments) ;

S

les élémentstheadettfoot, sont suivis par un ou plusieurs éléments de typetbodyoutr(il ne peut pas avoir les deux types d’éléments)

Selon cette définition, un tableau HTML minimal a la forme suivante : <table> <tr>...</tr> </table> ou <table> <tbody>...</tbody> </table>

Les élémentsT trU définissent des lignes du tableau. Pour créer un tableau complet avec des colonnes, il faut également connaître la définition de l’élément de typetr:

<!ELEMENT tr (th|td)+>

On voit que ceT trU a comme fils un ou plusieurs éléments de typethet/outddans n’importe quel ordre. Chaque élément d’un de ces deux types définit une colonne dans le tableau. La différence entreth ettdest que, dans le premier cas (th), le contenu est en général affiché en gras (header).

Contenu mixte

Les éléments de typetdetthpeuvent avoir un contenu mixte, c’est-à-dire contenir des sous-éléments mais également du texte. Voici un tableau complet exprimé en XHTML (les élémentsT tdU contiennent du texte) :

Exemple 57 TableauSimple.html : Tableau XHTML

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

<title>Page XHTML avec un tableau simple</title> </head>

4.1. DÉFINITION DE TYPES DE DOCUMENTS : DTD 159

<table border=’1’>

<tr><td>ligne <b>1</b>, colonne <b>1</b></td> <td>ligne <b>1</b>, colonne <b>2</b></td> </tr>

<tr><td>ligne <em>2</em>, colonne <em>1</em></td> <td>ligne <em>2</em>, colonne <em>2</em></td> </tr>

</table> </body> </html>

Le tableau a deux lignes, indiquées par les balises T trU dont chacune a deux colonnes (balises T tdU ). La figure 4.1 montre l’affichage par de cette page par Netscape.

Figure 4.1: Affichage de TableauSimple.html.

Les éléments de typetd et thpeuvent contenir des sous-éléments de plusieurs dizaines de types différents et une description détaillée dépasse le cadre de ce livre. Voici une définition très simplifiée du typetd:

<!ELEMENT td "(#PCDATA | table | p | b | em )*">

Cette dernière définition indique que les éléments de typetdcontiennent des sous-éléments de dif- férents types mélangés avec du texte dans n’importe quel ordre. En fait, il n’est pas possible de spécifier des contraintes plus fortes sur la structure d’un élément qui contient du texte mélangé avec des éléments. Par exemple, il n’est pas possible de spécifier qu’un élément de typetdcontient d’abord du texte suivi d’autres éléments comme dans l’exemple suivant :

<!-- Attention: La déclaration suivante n’est pas possible: --> <!ELEMENT td "(#PCDATA, (table | p | b | em )*)">

Définition récursives

La définition d’un type d’élémente donné peut contenir des types d’élémentsf qui utilisent déjàe dans leur propre définition. Si on regarde la définition (partielle) de la structure des éléments de typetd, on voit qu’une colonne d’un tableau peut à nouveau contenir un tableau, autrement dit qu’on peut créer des tableaux imbriqués. Voici un exemple (voir l’affichage 4.2)

,:

Exemple 58 TableauComplexe.html : Exemple d’un tableau imbriqué

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

</head> <body>

<table border="1">

<tr> <!-- première ligne du tableau "extérieur" --> <td> <!-- première colonne "extérieure" -->

<table border="1"> <!-- tableau "intérieur" --> <tr><td>1</td><td>2</td></tr>

<tr><td>3</td><td>4</td></tr> </table>

</td>

<td>a</td> <!-- deuxième colonne "extérieure" --> </tr>

<tr> <!-- deuxième ligne du tableau "extérieur" --> <td>b</td><td>c</td>

</tr> </table> </body> </html>

Figure 4.2: Copie d’écran de l’affichage d’un tableau imbriqué

4.1.4

Attributs

Une DTD sert également à spécifier les attributs permis pour chacun de ses types d’élément. Par exemple, dans le fichier TableauComplexe.html les éléments de typetablecontiennent chacun un attributborder, dont la valeur est égale à 1 (les champs du tableau doivent être entourés d’un cadre dont la largeur est un pixel). Cet attribut est défini dans la DTD XHTML de la manière suivante :

<!ATTLIST table border CDATA #IMPLIED>

Le mot réservé<!ATTLIST est suivi du nom de l’élément défini dans la DTD (table), du nom de l’attribut à définir (border), des informations sur le type de l’attribut (CDATA) et son utilisation (#IMPLIED). Le typeCDATAindique que les valeurs de cet attribut peuvent être des chaînes de caractères composées de tous les caractères sauf&,<et>. Le mot#IMPLIEDsignifie que cet attribut est optionnel.

Contrainte : Il ne peut avoir deux définitions d’attributs avec le même nom pour un élément. En revanche, il est possible de définir plusieurs attributs avec le même nom (et du même type ou de types différents) dans des éléments différents.

Dans la DTD XHTML, les éléments de typetdetth(champs dans une ligne d’un tableau) partagent exactement les mêmes attributs. Voici une version simplifiée :

4.1. DÉFINITION DE TYPES DE DOCUMENTS : DTD 161

rowspan CDATA "1" colspan CDATA "1">

L’attribut optionnelbgcolorpermet de définir la couleur de fond de la cellule. Les deux attributs (op- tionnels) suivants spécifient respectivement la hauteur (en lignes) et la largeur (en colonnes) de la cellule. Par défaut ces attributs prennent la valeur 1 : dans le cas d’un attribut optionnel avec valeur par défaut, le mot réservé#IMPLIEDest remplacé par la valeur par défaut.

Voici l’exemple d’un tableau plus complexe où les différents éléments ont des attributs (voir l’affichage dans la figure 4.3).

Exemple 59 TableauAttrs.html : Tableau avec attributs

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

<title>page xhtml avec un tableau complexe</title> </head>

<body>

<table border="1">

<tr><th rowspan="2"/><th bgcolor="gray" colspan="2">R</th></tr> <tr bgcolor="#aaaaaa"><th>A</th><th>B</th></t r>

<tr><th bgcolor="#aaaaaa">x</th><td>1</td><td>2</td></tr> </table>

</body> </html>

Figure 4.3: Affichage de TableauAttrs.html

La présence de certains attributs est parfois obligatoire dans la balise ouvrante d’un élément. Par ex-