Utilisation des feuilles XML et XSL pour le Web
CahiersGUTenberg n?33-34 — Congrès GUT’99 – Journée XML – 19 mai 1999
XML et XSL: un nouveau départ pour le web
Michel GOOSSENS
CERN, Division IT, CH-1211 Genève 23, Suisse, <>
Résumé. Fin 1996, le W3C et les plus grandes entreprises développant des logiciels pour l’internet se sont mis d’accord de collaborer pour définir un langage de balisage normalisé et optimisé pour le web: ce fut la naissance de XML (eXtensible Markup Language ou « langage extensible de balisage »). XML est basé sur SGML, dont il élimine un grand nombre de fonctions peu utilisées ou jugées trop complexes. De plus il évite la plupart des limitations inhérentes à ès une introduction au langage XML,nous décrivons XSL (eXtensible Style Language) qui permet la présentation et la transformation de l’information XML. Pour terminer nous disons quelques mots sur d’autres développements récents du monde XML.
Abstract. Late in 1996, the W3C and several major software vendors decided to define a markup language specifically optimized for the web: XML (eXtensible Markup Language) was born. It is a simple dialect of SGML,which does not use many of SGML’sseldom-used and complex functions, and does away with most limitations of HTML. After an introduction to the XML standard, we describe XSL (eXtensible Stylesheet Language)for presenting and transforming XML information.
Finally we say a few words about other recent developments in the XML arena.
Mot-clés : SGML, XML, XSL, HTML,XPath
1. Vers une description structurelle des documents
Dans l’environnement informatiséactuel, il est important que nos documents soient mis à la disposition d’une communauté aussi large que possible. Pour optimiser les possibilités de réutilisation de ces documents par les différents supports, visualisateurs, bases de données, etc., il est primordial que les documents soient clairement balisés structurellement, portables et indexables pour faciliter les recherches. Ceci nécessite une normalisation maximale à tous les niveaux. De plus il faut que les différents acteurs du monde de l’informatique suivent ces normes, ce qui n’est jamais acquis a priori. C’est pourquoi un maximum de développeurs doivent être impliqués dans la phase de définition de nouvelles normes, ce qui fut le cas de XML, dont nous parlerons plus loin.
1.1. Au début était SGML
Pour normaliser la description de la structure d’un document, SGML fut adopté par l’ISO en 1986[38]. Toutefois, SGML, qui propose à la fois une approche générale et ouverte, est assez complexe à mettre en œuvre. Pour la grande majorité des documents, surtout ceux distribuéssur l’internet, 20%seulement de la fonctionnalité de SGML est utilisée. Àl’origine, HTML tentait également de séparer les aspects structure et présentation d’un document. Malheureusement, Netscape et Microsoft, qui se livrent une bataille féroce pour contrôler le marché juteux de la distributionde l’information sur l’internet, en particulier grâce à leurs butineurs respectifs, recherchent principalement des gains commerciaux immédiats. Ainsi, pour attirer les utilisateurs, ils ont pollué le langage HTML par des extensions « maison », qui mettent en évidence les performances spécifiques de leurs produits. Évidemment ces extensions ne sont pas compatibles avec la spécification HTML comme définie par le W3C (World-Wide Web Consortium), ce qui rend le gestion des documents extrêmement problématique.
1.2. Puis vint XML
En réaction à cette tour de Babel des dialectes HTML, plusieurs acteurs du monde internet, comme Microsoft, Netscape et Sun, ont travaillé ensemble et ont défini un nouveau langage, qui combine les avantages de SGML et HTML : le langage de balisage extensible XML (Extensible Markup language) qui fut introduit officiellement le 10 février 1998 avec la publication de la recommandation XML[46]. XML est une version simplifiée de SGML qui doit assurer le libre échange des documents entre différentes applications internet.
2. Le langage XML
Tout comme son parent SGML [16], XML[24] est un méta-langage. Il permet la définition d’un langage pour décrire la structure de l’information pour un type de document donné en proposant un formalisme normalisé pour construire un langage de balisageadaptéaux besoins d’uneapplication spécifique. Ainsi XML et SGML diffèrent essentiellement de HTML, qui est une application de SGML avec une syntaxe figée et non extensible.
Pour chaque classe de documents XML (par exemple la famille HTML) nous pouvons définir une DTD (Data Type Declaration ou déclaration de classe de document), qui décrit les éléments et leurs attributs, les relations, le contenu, etc.
Pour simplifierletraitement des documents surleweb, XML n’imposepasla présence d’une DTD. En fait, un document XML doit avant tout être « bien-formé »: il se composed’unouplusieurséléments, dontunélément racine,qui contienttous lesautres.
De plus tous les éléments dudocument, délimités pas leurs balises de début et de fin, doivent être imbriqués correctement.
Un document XML bien-formé qui est correct par rapport à une DTD est dit « valide ». Dans ce cas on vérifie le document par rapport à sa grammaire.
Un document XML peut contenir des données textuelles ou binaires. Pour les données binaires aucune contrainte n’est imposée; il faut seulement qu’elles soient associées à une notation, identifiée par un nom, qui doit être communiqué aux applications traitant les données en question. Un fichier XML de type textuel contient des séquences de caractères. Un caractère est l’unité atomique d’un texte; tout caractère spécifié dans la norme Unicode[35, 2, 1] est autorisé.
Un nom XML commence par une lettre (caractère alphabétique ou idéographique d’Unicode) ou le caractère de soulignement (_) qui peut être suivi par une suite de caractères Unicode (à l’exception de quelques-uns).
Un texte XML est un mélange de données de type caractères et de marques. Ce marquage consiste en balises de début et balises de fin, d’éléments vides, de références de type entité ou caractère, des commentaires, des DTD et des instructions de traitement. Pour des raisons de place nous nous limiterons aux plus importantes.
2.1. Un document XML simplissime
Le document XML le plus simple (et « bien-formé ») a la forme:
<a>Je suis un document XML.</a>
Onn’a nul besoind’une DTD et c’estl’application XML (p.ex. leprogramme devisualisation) qui devra interpréter les actions associées à la balise <a>. Un autre fichier un peu plus complet, mais toujours pas valide, comme nous ne spécifions pas de DTD associé, est le suivant:
<?xml version="1.0"?>
<poème>Clair de Lune</poème>
Notons l’emploi d’un caractère accentué dans le nom de l’élément poème. En effet,
XML permet l’utilisationde noms d’éléments, d’attributs,etc. en russe, arabe, chinois ou japonais, ce qui n’a pas manqué d’accélérer le niveau d’adoption de la nouvelle norme dans les pays non-anglophones.
Le systèmede balisageest construit à partir de délimiteurs, de symboles spéciaux, de mots-clé ayant une signification particulière. Par exemple si « para » identifie l’élément « paragraphe », <para> sera la balise qui, dans le document, marque le début d’unparagraphe, « < » et « > » étant les délimiteurs indiquant respectivement le début et la fin de la balise. La balise de fin de paragraphe sera </para>.
2.2. Différences entre SGML et XML
Comme évoqué précédemment, XML a éliminé une grande partie de la fonctionalité générale de SGML (comme décrite dans [38, 11, 12]). On notera, en particulier, les points suivants:
– l’omission de balises est interdite, c’est-à-dire : chaque balise de début doit avoir une balise de fin correspondante;
– pour les élément vides il y a une nouvelle notation <a/> (<a></a> est aussi valable);
– les commentaires ont nécessairement la forme <!-- -->, c’est-à-dire : il est impossible d’inclure des commentaires à l’intérieur des déclarations d’éléments ou d’attributs;
– dans les modèles de contenu on ne peut utiliser des exclusions ou inclusions,ni l’opérateur et (&);
– toutes les valeurs des attributssont spécifiées entre une paire desimples (’)ou doubles (") quotes ;
– pour le nom des éléments et attributs, les majuscules et minuscules sont trai-tées comme des caractères distincts,donc <Para>,<para>et <PARA>sont des balises de trois éléments différents (en HTML classique la casse des caractères ne différencie pas les noms dans ce cas).
3. Anatomie d’une DTD pour un document XML
Comme nous l’avons indiqué ci-dessus une application XML peut traiter un document XML sans nécessairement avoir accès à la DTD décrivantla classe de documents pour le document en question. Néanmoins, il est primordial pour une bonne compréhension des possibilités du langage XML de rappeler la fonction et la structure de base d’une DTD. Il est à noter que la DTD peut être spécifiée en entier ou en partie à l’extérieur ou à l’intérieur d’un document source XML.
Une déclaration de type de document définit:
– le nom des types d’élément, leur contenu, y compris combien de fois et dans quel ordre d’autres éléments peuvent y apparaître (section 3.1);
– les attributs éventuels et leur valeurs par défaut (section 3.2); – le nom des entités qui peuvent être utilisées (section 3.3).
Comme la précision et la robustessede l’information baliséeen XML est un atout non négligeable, il est important de pouvoir vérifier les documents XML par rapport à une DTD. Ainsi, nous serons assurés de leur validité et nous pourrons les distribuer sur le web sans poser de problèmes aux applications qui pour des raison d’efficacité les interpréteraient sans référence à la DTD.
Il est utile de répéter qu’XML différencie la casse des caractères (présence de minuscules et majuscules)dans les noms des éléments (balises), desattributset des entités, qui doivent donc toujours être entrés textuellement.
3.1. Éléments
Chaque typed’élément dela structurelogiqued’undocument doitêtredéclaré. Cette déclaration donne le nom du type de l’élément et indique, entre parenthèses, ce que peut, ou doit contenir l’élément en question (son modèle de contenu). Un exemple est le suivant:
<!ELEMENT mémo (entête, contenu, ps?)>
Ce modèle indique que l’élément « mémo » doit contenir un élément entête, suivi d’un contenu,puis peut (sans obligation) être suivi d’un élément ps.
Le modèle de contenu peut faire appel à des opérateurs d’ordre et de choix, comme suit:
a | b a ou b (dans n’importe quel ordre); a , b a suivi de b (dans l’ordre indiqué); a une fois l’élément a; a? zéro ou une fois l’élément a; a* zéro ou plusieurs fois l’élément a; a+ au moins une fois l’élément a; ( ) un groupe d’éléments.
Un élément peut être vide (mot clé EMPTY), il peut contenir d’autres éléments, des caractères, ou un mélange des deux: dans ce dernier cas on parle de contenu mixte. Pour un contenu mixte XML est très strict: ni le nombre ni l’ordre des éléments ne peuvent être spécifiés explicitement et le mot clé #PCDATA doit être le premier dans le modèle de contenu:
1 <!ELEMENT br EMPTY>
2 <!ELEMENT livre (chapitre+,annexe*,biblio?,index?>
3 <!ELEMENT e1 (#PCDATA)>
4 <!ELEMENT e2 (#PCDATA|a1|a2|a3)*>
5 <!ELEMENT e3 (#PCDATA | %ent1; | %ent2;)* >
La première ligne déclare l’élément br comme étant vide. La deuxième ligne déclare qu’un livre contient au moins un élément chapitre, puis aucun ou plusieurs éléments annexe, puis aucun ou un élément biblio suivi d’un éventuel élément index. La ligne 3 déclare que l’élément e1 ne contient que des données textuelles analysées, alors que la ligne 4 déclare que l’élément e2 peut contenir des données textuelles analysées, ainsi que les éléments a1, a2 et a3 (toutefois nous ne savons rien concernant le nombre d’occurrences, ni de leur ordre). La dernière ligne, qui fait référence à des entités paramètres, sera expliquée à la section 3.3.
Finalement, si un élément peut contenir des caractères ou tout autre élément défini dans la DTD nous utilisons le mot-clé ANY. Ce type de déclaration n’est pas très riche en information pour limiter la structure d’un document, mais a son utilité comme élément « conteneur » générique.
<!ELEMENT container ANY>
3.2. Attributs
Les attributs permettent d’associer des paires nom-valeur aux éléments définis dans la DTD. Des attributs peuvent seulement être spécifiés à l’intérieur d’une balise de début ou d’élément vide. Les définitions d’attribut spécifient:
– la liste exhaustive des noms d’attribut associés à un élément;– le type des attributs en question; – une valeur par défaut.
Une déclaration d’attribut comporte:
– le nom de l’élément;
– le nom de l’attribut;
– soit le type de l’attribut, indiqué par un mot-clé:
CDATA | données textuelles (caractères quelconques); |
ENTITY | nom d’entité générale; |
ENTITIES | noms d’entités générales ; |
ID | identificateur unique d’un élément; |
IDREF | valeur d’appel d’identificateur d’élément; |
IDREFS | valeurs d’appel d’identificateurs d’élément; |
NMTOKEN | unité lexicale nominale; |
NMTOKENS | unités lexicales nominales; |
NOTATION | nom de notation. |
Alternativement on spécifie, entre parenthèses, la liste de toutes les valeurs possibles pour cet attribut;
– une valeur par défaut, sous la forme d’une des valeurs autorisées, spécifiéeentre guillemets, ou d’un mot-clé:
#FIXED l’attribut a une valeur fixe, et ne peut prendre que cette valeur;
#REQUIRED une valeur doit obligatoirement être spécifiée par l’utilisateur;
#IMPLIED si une valeur n’est pas spécifiée, le système de traitement en définira une.
Voici un exemple, qui combine quelques-unes des possibilités évoquées. Dans le cas de l’attribut type la DTD doit contenir une définition de type NOTATION pour chacune des valeurs mentionnées, avec un renvoi vers une ressource système ou publique pour traiter les données associées à l’élément en question (p.ex. un programme de visualisation capable de décoder le format graphique choisi).
<!ATTLIST image source %URL #REQUIRED id ID #REQUIRED
nom CDATA #IMPLIED échelle "1.0" #FIXED fond (rouge|bleu|jaune) "bleu" type NOTATION (eps|gif|bmp|tiff) "eps">
3.3. Entités
Des entités peuvent être utiles dans plusieurs circonstances:
– la définitiondecaractères difficilesou impossiblesà saisiravec un clavier stan-dard (caractères nationaux, symboles graphiques et mathématiques). Avec un appel de caractère nous spécifions directement le code Unicode du caractère en question, par exemple l’esperluette (&) est le caractère 38 en Ascii:
<!ENTITY amp CDATA "&">
Pour undocument bien-formé, XML prédéfinitles entitésamp(&),lt(<),gt(>), apos (’) et quot ("). Par contre, pour tout document valide ces entités doivent nécessairement être déclarées dans la DTD. Notons qu’avec XML on a accès par défaut à tous les caractères définis par Unicode[35, 2].
– La définition de notations raccourcies pour des suites de caractères saisies fré-quemment (entités générales) p.ex.
<!ENTITY Seuil "<em>Éditions du Seuil</em>">
– L’inclusion de fichiers externes, par exemples les différentes parties d’un longdocuments XML, ou des documents non-XML (entités externes) p.ex.
<!ENTITY poème3 SYSTEM "">
– La définition de variables dans une DTD pour en faciliter la structuration logique (entités paramètres) p.ex.
<!ENTITY % préambule " titre | recueil | date | auteur ">
Les entités sont déclarées dans la DTD (dans le sous-ensemble interne ou externe). Comme nous l’avons montré dans les exemples ci-dessus, la définition d’une entité peut contenir des balises,desappels d’entités,etc., qui seront interprétés aumoment où l’entité sera développée par le programme d’analyse XML.
Pour faire référence à une entité générale on utilise un appel d’entité, qui a la forme & suivi du nom de l’entité suivi de ;. Par exemple pour utiliser l’entité Seuil définie ci-dessus nous saisissonsdans le texte &Seuil;ce qui générera la suitede caractères « <em>Éditions du Seuil</em> ».
Les entités paramètres, qui peuvent seulement être définies et utilisées à l’intérieur de la DTD sont un outil commode pour modulariser la structure d’une DTD et ainsi la rendre plus lisible et plus facile à tenir à jour ou à modifier. Tout définition d’une entité paramètre doit précéder son utilisation.
3.4. Exemple : un poème de Verlaine
Dans ce qui suitnous allons utiliserplusieurs types dedocuments, et chaque foisleur structure sera décrite à l’aide d’une ou de plusieurs DTD. Supposons que nous voulions créer une DTD pour saisir des poèmes. Comme exemple de texte nous utiliserons la célèbre « Chansond’automne » dePaul Verlaine (durecueil Poèmes saturniens édité en 1866). Regardons le texte en question.
Les sanglots longs Je me souviens
Des violons Des jours anciens De l’automne Et je pleure;
Blessent mon coeur Et je m’en vais
D’une langueur Au vent mauvais
Monotone. Qui m’emporte Tout suffocant Deçà, delà,
Et blême, quand Pareil à la Sonne l’heure, Feuille morte.
3.4.1. Première réalisation : les éléments triomphent
Nousvoulonspouvoirspécifier letitredupoème, sonauteur,peut-être lerecueil dont il a été tiré et sa date d’édition. Tout mettrons tout cela un préambule. Pour le corps d’un poème nous préconisons de le diviser en stances qui, à leur tour, contiennent des lignes, avec ou sans renfoncement. La DTD ci-dessous est une première réalisation du cahier de charges évoqué où nous codons toute l’information à l’aide d’éléments.
La seule partie dans cette DTD que nous n’avons pas encore rencontrée est la première ligne. Elle est optionnelle et correspond à la déclaration XML. Elle spécifie la version de XML utilisée (mot-clé version) qui peut être suivie du codage (mot-clé encoding)et une spécification si le document peut être traité seul, c’est-à-dire : sans devoir faire appel à des déclarations d’éléments dans une DTD externe, auquel cas on ajoute « standalone="yes"», ou sinon « standalone="no"».
Voici le fichier source de la DTD, :
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!-- : DTD pour poésie M. Goossens --> 3 <!-- poème contient un préambule suivi d’un corps -->
4 <!ELEMENT poème (préambule, corps)>
5 <!-- préambule doit contenir un titre,
6 peut-être suivi du nom du recueil,
7 peut-être suivi de la date de composition,
8 doit être suivi du nom de l’auteur -->
9 <!ELEMENT préambule (titre, recueil?, date?, auteur)>
10 <!-- titre contient des caractères -->
11 <!ELEMENT titre (#PCDATA)>
12 <!-- recueil contient des caractères -->
13 <!ELEMENT recueil (#PCDATA)>
14 <!-- date contient des caractères -->
15 <!ELEMENT date (#PCDATA)>
16 <!-- auteur contient des caractères -->
17 <!ELEMENT auteur (#PCDATA)>
18 <!-- corps a des lignes, regroupées ou non en stances -->
19 <!ELEMENT corps (stance|ligne)+>
20 <!-- stance composée de lignes -->
21 <!ELEMENT stance (ligne)+>
22 <!-- ligne contient caractères et (peut-être) renfoncements -->
23 <!ELEMENT ligne (#PCDATA|r)*>
24 <!-- renfoncement contient des caractères -->
25 <!ELEMENT r EMPTY>
Maintenant nous pouvons baliser notre poème en utilisant cette DTD. Nous montrons le fichier source XML ci-dessous. La deuxième ligne y correspond à une déclaration de type de document (mot-clé DOCTYPE). Dans ce cas elle spécifie que le document a comme racine l’élément poème dont la structure est définie dans une DTD qui se trouve dans le fichier ,qui est disponible sur le système (mot-clé SYSTEM) où le document est traité.
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE poème SYSTEM "">
3 <poème>
4 <préambule>
5 <titre>Chanson d’automne</titre>
6 <recueil>Poèmes saturniens</recueil>
7 <date>1866</date>
8 <auteur>Paul Verlaine</auteur>
9 </préambule>
10 <corps>
11 <stance>
12 <ligne>Les sanglots longs</ligne>
13 <ligne>Des violons</ligne>
14 <ligne><r/>De l’automne</ligne>
15 <ligne>Blessent mon coeur</ligne>
16 <ligne>D’une langueur</ligne>
17 <ligne><r/>Monotone.</ligne>
18 </stance>
19 <stance>
20 <ligne>Tout suffocant</ligne>
21 <ligne>Et blême, quand</ligne>
22 <ligne><r/>Sonne l’heure,</ligne>
23 </stance>
24 <stance>
25 <ligne>Je me souviens</ligne>
26 <ligne>Des jours anciens</ligne>
27 <ligne><r/>Et je pleure ;</ligne>
28 </stance>
29 <stance>
30 <ligne>Et je m’en vais</ligne> 31 <ligne>Au vent mauvais</ligne>
32 <ligne><r/>Qui m’emporte</ligne>
33 <ligne>Deçà, delà,</ligne> 34 <ligne>Pareil à la</ligne>
35 <ligne><r/>Feuille morte.</ligne>
36 </stance>
37 </corps>
38 </poème>
À l’aide d’un programme d’analyse nous pouvons vérifier si le fichier XML est valide. Nous lefaisons,par exemple, avec xml4j[21],unprogramme Javadéveloppé par IBM qui peut valider des documents XML.
> java XJParse -p .parsers.ValidatingSAXParser
: 460 ms (35 elems, 0 attrs, 49 spaces, 300 chars)
Le même programme offre la possibilité d’obtenir une vue en arbre du document.
> java ui.TreeViewer
:
START
START
START
START
END
END
END
Le résultat est montré à la figure 1. Nous y voyons dans la fenêtre de gauche les différentes parties de l’arbre, que l’on peut traverser facilement en ouvrant ou fermant certains éléments (visibles comme dossier). À droite nous avons le fichier source.
FIGURE 1 – Représentation en arbre du document
Nous pouvons aussi traiter ce fichier avec le programme d’analyse SGML nsgmls[6] de James CLARK et obtenir une sortie [7]. Nous devons toutefois indiquer qu’il s’agit d’un fichier XML, d’où la présence du fichier (la déclaration SGML adaptée pour XML) sur la ligne de commande ci-dessous.
> nsgmls
1 (poème
2 (préambule
3 (titre
4 -Chanson d’automne
5 )titre
6 (recueil
7 -Poèmes saturniens
8 )recueil
9 (date 10 -1866
11 )date
12 (auteur
13 -Paul Verlaine
14 )auteur
15 )préambule
16 (corps
17 (stance
18 (ligne
19 -Les sanglots longs
20 )ligne
21 (ligne
22 -Des violons
23 )ligne
24 (ligne
25 (r
26 )r
27 -De l’automne
28 )ligne
29 (ligne
30 -Blessent mon coeur
31 )ligne
32 (ligne
33 -D’une langueur
34 )ligne
35 (ligne
36 (r
37 )r
38 -Monotone.
39 )ligne
40 )stance
41 (stance
42 (ligne
43 -Tout suffocant
44 )ligne
45 (ligne
46 -Et blême, quand
47 )ligne
48 (ligne
49 (r
50 )r 51 -Sonne l’heure,
52 )ligne
53 )stance
54 (stance
55 (ligne
56 -Je me souviens
57 )ligne
58 (ligne
59 -Des jours anciens
60 )ligne
61 (ligne
62 (r
63 )r
64 -Et je pleure ;
65 )ligne
66 )stance
67 (stance
68 (ligne
69 -Et je m’en vais
70 )ligne
71 (ligne
72 -Au vent mauvais
73 )ligne
74 (ligne
75 (r
76 )r
77 -Qui m’emporte
78 )ligne
79 (ligne
80 -Deçà, delà,
81 )ligne
82 (ligne
83 -Pareil à la
84 )ligne
85 (ligne
86 (r
87 )r 88 -Feuille morte.
89 )ligne
90 )stance
91 )corps
92 )poème
93 C
La signification des différentes composantes de cette sortie est détaillée à l’URL nous, il suffit de savoir que les parenthèses représentent les éléments et qu’ils sont étiquetés du nom de l’élément en question. Le contenu de l’élément est contenu entre la parenthèse ouverte et la parenthèse fermée (par exemple le contenu de l’élément préambule commence à la ligne 2 et finit à la ligne 15). Les attributs commencent par un A majuscule (voir fichier à la page 15).
3.4.2. Deuxième variante: un savant mélange d’éléments et d’attributs
En général il y a plusieurs manières pour approcher la définition d’une DTD, qui décrit la façon dont nous voulons structurer les données dans notre document XML. Une approche assez traditionnelle balisant pratiquement toute l’information à l’aide d’éléments a été présentée. Nous pouvons tout aussi bien préférer de baliser uniquement le texte du poème à l’aide d’éléments et de spécifier tous les autres détails avec des attributs. C’est l’approche adoptée dans notre deuxième variante de DTD que nous avons baptisée poemfr1.dtdet qui a la forme suivante:
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!-- : DTD pour poésie M. Goossens --> 3 <!-- poème contient un préambule suivi d’un corps --> 4 <!ELEMENT poème (préambule, corps)>
5 <!-- préambule : élément vide -->
6 <!ELEMENT préambule EMPTY>
7 <!-- attributs de type caractères pour titre, nom du recueil -->
8 <!-- date d’édition et nom de l’auteur -->
9 <!ATTLIST préambule titre CDATA #IMPLIED
10 recueil CDATA #IMPLIED 11 date CDATA #IMPLIED
12 auteur CDATA #IMPLIED>
13 <!-- le corps contient des lignes -->
14 <!ELEMENT corps (ligne)+>
15 <!-- ligne contient caractères -->
16 <!ELEMENT ligne (#PCDATA)*>
17 <!-- ligne peut commencer nouvelle stance ou contenir renfoncement -->
18 <!ATTLIST ligne stance (oui|non) "non"
19 r CDATA "0em" >
Voici le fichier verlainefr1.xmlqui contient du poème balisé d’après cette DTD.
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE poème SYSTEM "" [
3 <!ENTITY r "6pt">
4 ]>
5
6 <poème>
7 <préambule titre="Chanson d’automne"
8 recueil="Poèmes saturniens"
9 date="1866"
10 auteur="Paul Verlaine"/>
11 <corps>
12 <ligne stance="oui">Les sanglots longs</ligne>
13 <ligne>Des violons</ligne>
14 <ligne r="1em">De l’automne</ligne>
15 <ligne>Blessent mon coeur</ligne> 16 <ligne>D’une langueur</ligne>
17 <ligne r=".5em">Monotone.</ligne>
18 <ligne stance="oui">Tout suffocant</ligne>
19 <ligne>Et blême, quand</ligne>
20 <ligne r="&r;">Sonne l’heure,</ligne>
21 <ligne stance="oui">Je me souviens</ligne>
22 <ligne>Des jours anciens</ligne>
23 <ligne r="6pt">Et je pleure ;</ligne>
24 <ligne stance="oui">Et je m’en vais</ligne>
25 <ligne>Au vent mauvais</ligne>
26 <ligne r="&r;">Qui m’emporte</ligne>
27 <ligne>Deçà, delà,</ligne> 28 <ligne>Pareil à la</ligne>
29 <ligne r="1em">Feuille morte.</ligne>
30 </corps>
31 </poème>
Les informations concernant auteur, titre, etc., (lignes 7–10) ainsi que les débuts des stances (lignes 12, 18, 21, 24) et les renfoncements éventuels (lignes 14, 17, etc.) sont ici codés à l’aide d’attributs. Nous vérifions la validité du fichier avec xml4j.
> java XJParse -p .parsers.ValidatingSAXParser
: 499 ms (21 elems, 40 attrs, 36 spaces, 249 chars)
La figure 2 est une représentation par l’application xmlviewer[20] du document vue en arbre est dans la fenêtre en haut à gauche, les attributs de l’élément mis en évidence à droite, puis on trouve le document source en bas à gauche et finalement la DTD à droite. Cette application est très intéressante pour naviguer à travers un document XML. java .xmlviewer.XmlViewer
Nous montrons également une partie de la sortie obtenue avec le programme nsgmls.
FIGURE 2 – Le documentvu par l’application xmlviewer
1 (poème
2 Atitre CDATA Chanson d’automne
3 Arecueil CDATA Poèmes saturniens
4 Adate CDATA 1866
5 Aauteur CDATA Paul Verlaine
6 (préambule
7 )préambule
8 (corps
9 Astance TOKEN oui
10 Ar CDATA 0em
11 (ligne
12 -Les sanglots longs
13 )ligne
14 Astance TOKEN non
15 Ar CDATA 0em 16 (ligne
17 -Des violons
18 )ligne
19
20 Astance TOKEN non
21 Ar CDATA 6pt
22 (ligne
23 -Qui m’emporte
24 )ligne
25 Astance TOKEN non
26 Ar CDATA 0em
27 (ligne
28 -Deçà, delà,
29 )ligne
30 Astance TOKEN non
31 Ar CDATA 0em
32 (ligne
33 -Pareil à la
34 )ligne
35 Astance TOKEN non
36 Ar CDATA 1em
37 (ligne 38 -Feuille morte.
39 )ligne
40 )corps
41 )poème
42 C
Nous y observons clairement la présence des attributs et de leur valeur (par exemple la ligne 2 indique que titre est de type CDAT et a la valeur « Chanson d’automne »). Notons également que les valeurs par défaut sont utiliséespour les attributsnon spécifiés explicitement (ainsi en ligne 14 stance a la valeur non et en ligne 15 r une valeur égale a 0em).
3.4.3. Variante ultime : rien que des attributs
Nous pouvons même aller à l’extrême et spécifier tout le poème comme valeurs d’attributs.Cette ultime approche montre également comment étendre une DTD en spécifiant des attributs supplémentaires à ceux déjà définis dans le sous-ensemble externe de la DTD. Ceci se fait dans le sous-ensemble interne de la DTD, c’est-à-dire : dans la partie déclaration de balisage à l’intérieur de la déclaration de type de document. C’est ce qui est montré ci-dessous en lignes 3–8. XML permet plusieurs instructions pour les définitions d’attributs <!ATTLIST > pour un élément donné: toutes les définitions sont combinées. On peut même donner plusieurs définitions pour le même attribut pour un élément donné. Toutefois dans ce cas, seule la première définition est prise en compte et les définitions ultérieures sont ignorées. Comme le sous-ensemble interne de la DTD est lu avant le sous-ensemble externe, dans notre cas les définitions en lignes 3–7 dans le fichier verlainefr2.xmlmontré ci-dessous sont lues avant celles dans le fichier DTD éférencé en ligne 2.
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE poème SYSTEM "" [
3 <!ENTITY r "1em">
4 <!-- le numéro de la ligne (défaut : pas de numéro) -->
5 <!ATTLIST ligne nb CDATA " " >
6 <!-- le texte de la ligne (défaut : pas de texte) -->
7 <!ATTLIST ligne texte CDATA " " >
8 ]>
9 <poème>
10 <préambule titre="Chanson d’automne"
11 recueil="Poèmes saturniens"
12 date="1866"
13 auteur="Paul Verlaine"/>
14 <corps>
15 <ligne stance="oui" nb="1" texte="Les sanglots longs"/>
16 | <ligne | nb="2" texte="Des violons"/> |
17 | <ligne r="&r;" | nb="3" texte="De l’automne"/> |
18 | <ligne | nb="4" texte="Blessent mon coeur"/> |
19 | <ligne | nb="5" texte="D’une langueur"/> |
20 | <ligne r="&r;" | nb="6" texte="Monotone."/> |
21 <ligne stance="oui" nb="7" texte="Tout suffocant"/>
22 <ligne nb="8" texte="Et blême, quand"/>
23 <ligne r="&r;" nb="9" texte="Sonne l’heure,"/> 24 <ligne stance="oui" nb="10" texte="Je me souviens"/>
25 <ligne nb="11" texte="Des jours anciens"/>
26 <ligne r="&r;" nb="12" texte="Et je pleure ;"/>
27 <ligne stance="oui" nb="13" texte="Et je m’en vais"/>
28 | <ligne | nb="14" texte="Au vent mauvais"/> |
29 | <ligne r="&r;" | nb="15" texte="Qui m’emporte"/> |
30 | <ligne | nb="16" texte="Deçà, delà,"/> |
31 | <ligne | nb="17" texte="Pareil à la"/> |
32 | <ligne r="&r;" | nb="18" texte="Feuille morte."/> |
33 | </corps> | |
34 | </poème> |
Nous avons balisél’élément <ligne>comme s’ilétait élément vide, même si, dans la
DTD,iln’apasétédéfinicommetel.Cebalisageexpliciteetcompletesttrèscommode pour gérer des textes dans les bases de données, comme il est simple d’en extraire n’importe quel type d’information. Évidemment pour chaque DTD une nouvelle déclaration XSL devra être développée pour visualiser le document (voir la section 5).
4. Domaines nominaux
Les domaines nominaux (namespaces[41]) permettent de garantir l’unicité des noms d’éléments et d’attributs même lorsque plusieurs DTD (modules ou logiciels) sont combinées. En effet il n’est pas rare que des noms identiques soient utilisés dans ces modules à des fins différentes. La spécification définissant les domaines nominaux introduit une méthode pour délimiter la partie du document où un nom est visible en créant un « domaine de validité » comme suit:
– un domaine nominal est un ensemble de noms caractérisé par un URI [22];
– cet URI identifie d’une façon unique les noms de types d’élément et d’attribut appartenant à ce domaine nominal;
– cet URI ne doit pas correspondre à une ressource réelle; – cet URI servira comme préfixe pour rendre un nom non-ambigu.
Undomainenominal estdéfini àl’aided’uneséried’attributsréservés. Untelattribut sera la chaîne de caractères xmlns ou aura la chaîne xmlns: comme préfixe.
Le double point est utilisé pour séparer le préfixe identifiant le domaine nominal de la partie locale, les deux unités ensemble formant un « nom qualifié » (voir les règles de production à la section B pour plus de détails).
1 <xsl:stylesheet xmlns:xsl=";
2 xmlns:fo=";>
3 <xsl:template match="emph">
4 <fo:sequence font-style="italic">
5 <xsl:apply-templates/>
6 </fo:sequence>
7 </xsl:template>
Dans l’exemple précédent nous voyons comment le préfixe xmlns: permet de définir l’abréviation qui sera utilisée pour identifier un domaine nominal. Ainsi « xsl: » en ligne 1 est déclaré correspondre à la chaîne Transform, alors que la ligne 2 déclare fo: comme représentant la chaîne http:
La partie locale du nom qualifié—template en ligne 3 ou apply-templates en ligne 5 et sequence en ligne 4—doit avoir un sens dans le domaine nominal en question—xsl et fo dans notre cas.
Un domaine nominal par défaut peut être indiqué comme à la ligne 3 ci-dessous, qui spécifie que les noms non préfixés (comme le <p> en ligne 5) appartiennent au domaine nominal XHTML
1 <xsl:stylesheet
2 xmlns:xsl=";
3 xmlns=";
4 <xsl:template match="par">
5 <p><xsl:apply-templates/></p>
6 </xsl:template>
4.1. Déclarer un domaine nominal pour un élément
Une déclaration de domaine nominal est valable pour l’élément où elle est spécifiée et pour tous les éléments contenus dans cet élément, à moins qu’une autre déclaration de domaine nominal utilisant la même partie abréviation ne soit rencontrée. Ainsi, les domaines nominaux peuvent se chevaucher et être redéfinis localement comme le montre l’exemple suivant:
1 <?xml version=’1.0’?>
2
3 <particules>
4 <!-- Domaine nominal devient XHTML -->
5 <table xmlns=’’>
6 <tr><td>Particule</td><td>Masse</td><td>Détails</td></tr>
7 <tr>
8 <td><em>neutron</em></td>
9 <td>939.56 MeV</td>
10 <td>
11 <pdg xmlns="autreDomNom">
12 <!-- Ici le domaine nominal change localement -->
13 <quarks>udd</quarks><duréeDeVie>886.7 s</duréeDeVie>
14 <désintégration>p,e,anue</désintégration>
15 </pdg>
16 </td><!-- À partir d’ici nous retrouvons XHTML -->
17 </tr>
18 </table>
19 <!-- Retour au domaine original -->
20 </particules>
21
De la ligne 5 à la ligne 18, le domaine nominal par défaut est celui de XHTML. Par contre, en ligne 11 nous redéfinissons le domaine nominal par défaut qui devient autreDomNom pour l’élément pdg et ses descendants. Il reste effectif jusqu’en ligne 15 où nous quittons le cadre de l’élément pdg.
Si nous voulons éliminer toute référence à un domaine nominal nous pouvons spécifier un URI vide (xmlns=""). Dans ce cas les éléments sans préfixe nominal dans le domaine de validité de la déclaration n’ appartiennent à aucun domaine nominal. Notons toutefois (voir exemple ci-dessous) que le domaine nominal par défaut ne s’applique par directement aux attributs.
4.2. Déclarer un domaine nominal pour un attribut
Les domaines nominaux s’appliquent aussi aux attributs. Notons qu’une balise XML ne peut contenir deux attributs avec un nom identique (en accord avec la section 3.1 de la spécification XML), ni avec des noms qualifiés ayant une même partie locale et des préfixes liés à des domaines nominaux identiques.
1 <ex xmlns:d1=""
2 xmlns:d2="" >
3 xmlns="" >
4 <faux a="1" a="2" />
5 <faux d1:a="1" d2:a="2" /> 6 <bien a="1" b="2" />
7 <bien a="1" d1:a="2" />
8 </ex>
Dans cet exemple, les lignes 1–3 définissent trois domaines nominaux (d1, d2 et le défaut) qui correspondent tous à l’URI ligne 4 estillégale(les deuxattributsont lemêmenom), toutcommela ligne5(lesdeux attributs ont une même partie locale et des domaines nominaux liés à un URL identique). Par contre la ligne 6 dont les deux attributs ont un nom différent est légale. La ligne 7 est également correcte car le domaine nominal par défaut ne s’applique pas aux attributs.
5. Le langage XSL
La spécificationdulangage XSL (Extensible Stylesheet Language ou langageextensible pour feuilles de style) est divisée en trois parties:
1. XPath[48]: un langage pour adresser une partie d’un document XML. Il est utilisé avec les recommandations XSLT et XPointer.
2. XSLT [53]: un langage pour transformer les documents XML en d’autres documents XML.
3. XSLF [52]: unvocabulairepour spécifier le formataged’un document XML. XSLF utiliseunefeuilledestyle XSLT pour transformer ledocument source XML enun autre document XML qui utilise les éléments du vocabulaire de formatage.
Actuellement la plupart des applications de XSL n’utilisent que les parties XPath et
XSLT. Nous les traiterons en priorité et ne mentionnerons qu’en passant quelques caractéristiques de XSLF, dont la spécification n’est pas encore finalisée. En complément à l’information sur XSL dans ses pages nous suggérons des tutoriels, listes de discussions et foire aux questions dans [27, 26, 8, 25, 17].
5.1. Le langage XPath
Le langage XPath propose une syntaxe et sémantique communes pour les fonctions partagées entre XSLT et XPointer[49]. Le but principal de XPath est d’adresser les différentes parties d’un document XML. XPath propose également quelques fonctions pour manipuler les suites de caractères, les nombres et les booléens. La syntaxe du langage XPath adopte une syntaxe compacte non-XML, qui permet son utilisation dans les URIs et à l’intérieur des attributs XML.
XPathmodéliseundocument XML commeunarbredenœuds (detypeélément, attribut, texte, etc..). XPath permet de calculer une valeur de type caractère pour chaque type de nœud. La construction syntaxique principale de XPath est l’expression dont l’évaluation peut donner quatre types d’objets: un ensemble (une collection nonordonnée) de nœuds, un booléen (« vrai » ou « faux ») , un nombre (virgule flottante) ou une chaîne de caractères (une séquence de caractères Unicode).
5.1.1. Chemins de localisation
Un chemin de localisation (location path) est le type d’expression le plus commun de XPath. Il utilise treize axes pour se déplacer dans le document.
child contient les descendants immédiats (les « enfants ») du nœud contexte, en d’autres mots le nœud par rapport auquel on spécifie le chemin de localisation. Les nœuds de type attribut ou domaine nominal ne sont pas considérés comme des descendants du l’élément contenant.
child::section choisit les nœuds de type section qui sont des descendants immédiats du nœud contexte, child::* choisit tous les descendants directs du nœud contexte.
descendant contient tous les descendants (enfants, petits-enfants, ) du nœud contexte. Comme pour l’axe child cet axe ne contient jamais de nœuds de type attribut ou domaine nominal.
descendant::soussectionchoisitlesnœudsdetypesoussectionquisont des descendants du nœud contexte.
parent contientl’ascendantimmédiat(parentausens« père»ou«mère»)dunœud contexte, s’il existe. Pour un nœud de type attribut et domaine nominal il s’agit de l’élément auquel le nœud en question est attaché (l’élément « contenant »). parent::article choisit l’ascendant immédiat de type article du nœud contexte.
ancestor contient lesascendants(parent, grand-parent, etc.)dunœudcontexte. Le parent sera le premier sur l’axe, le parent du parent le deuxième, etc.
ancestor::articlechoisit l’ascendant de type articledu nœud contexte.
following-sibling contient les nœuds qui suivent le nœud contexte et qui ont le même parent que ce dernier (c’est-à-dire : les « frères » et « sœurs »). Pour un nœud de type attribut ou domaine nominal l’axe following-siblingest vide.
preceding-sibling contient les nœuds qui précèdent le nœud contexte et qui ont le même parent que ce dernier. Pour un nœud de type attribut ou domaine nominal l’axe following-siblingest vide.
following contient tous les nœuds dans le même document que le nœud contexte qui le suivent d’après l’ordre dans le document, en excluant les descendants et les nœuds de type attribut ou domaine nominal.
preceding contient tous les nœuds dans le même document que le nœud contexte qui le précèdent d’après l’ordre dans le document, en excluant les ascendants et les nœuds de type attribut ou domaine nominal.
self ne contient que le nœud contexte.
descendant-or-self contient lenœud contexte et ses descendants; le nœud contexte est le premier nœud sur l’axe, son premier enfant le deuxième, et ainsi de suite (voir l’axe descendant).
ancestor-or-self contient lenœud contexte et ses ascendants; lenœud contexte est le premier nœud sur l’axe, son parent le deuxième, et ainsi de suite (voir l’axe parent).
attribute contient les attributs du nœud contexte. Si le nœud contexte n’est pas de type élément l’axe sera vide.
namespace contient les nœuds de type domaine nominal du nœud contexte. L’axe est vide si le nœud contexte n’est pas de type élément.
Pour certains cas il existe une notation courte d’après le schéma suivant (la forme courte est à gauche, son équivalent long à droite): nom child::nom @nom attribute::nom . self::node()
.. parent::node()
// descendant-or-self::node()
Voici quelques exemples de l’utilisationdeces axes (avec la forme courte équivalente si elle existe):
– "child::section"choisit les enfants de type section du nœud contexte. "section"en est la forme courte.
– "child::text()"choisit les nœuds enfants de type texte du nœud contexte.
"texte()"en est la forme courte.
– "child::node()"choisit tous les nœuds enfants du nœud contexte indépendamment du type du nœud. "node()"en est la forme courte.
– "attribute::couleur"choisit l’attribut ayant le nom couleur du nœud contexte. "@couleur"en est la forme courte.
– "attribute::*"choisit tous les attributs du nœud contexte.
"@*" en est la forme courte.
– "descendant::soussection"choisit les descendants de type soussectiondu nœud contexte.
– "ancestor::soussection"choisit les ascendants de type soussectiondu nœud contexte.
– "ancestor-or-self::soussection"choisit les ascendants de type soussectiondu nœud contexte ainsi que le nœud contexte lui-même s’il correspond au type d’élément soussection.
– "descendant-or-self::soussection"choisit les descendants de type soussectiondu nœud contexte ainsi que le nœud contexte lui-même s’il correspond au type d’élément soussection.
"//soussection"en est la forme courte.
– "self::soussection"choisit le nœud contexte s’il correspond au type d’élément soussection,autrement ne choisit rien.
– "child::section/descendant::soussection"choisit les descendants de type soussectiondes enfants de type section du nœud contexte.
"section//soussection"en est la forme courte.
– "child::*/child::para"choisit tous les petits-enfants de type para du nœud contexte.
– "/" sélectionne la racine du document (qui est toujours le parent de l’élément document (voir la production [1] de la grammaire de XML).
– "/descendant::liste/child::item"choisit tous les éléments de type item dans le même document que le nœud contexte qui ont un parent de type liste (le / initial indique que nous commençons à la racine du document).
– "child::liste[position()=2]"choisit le deuxième enfant de type liste du nœud contexte. "liste[2]"en est la forme courte.
– "child::liste[position()=last()]"choisit le dernier enfant de type liste du nœud contexte. "liste[last()]"en est la forme courte.
– "child::liste[position()=last()-1]"choisit l’avant-dernier enfant de type liste du nœud contexte. "liste[last()-1]"en est la forme courte.
– "child::liste[position()=>3]"choisit tous les enfants de type liste du nœud contexte sauf les deux premiers.
"liste[position()=>3]"en est la forme courte.
– "following-sibling::section[position()=1]"choisit le prochain élément de type section qui a le même parent que le nœud contexte.
– "preceding-sibling::section[position()=1]"choisit le précédent élément de type sectionqui a le même parent que le nœud contexte.
– "/descendant::figure[position()=17]"choisit le dix-septième élément de type figure dans le document.
"//figure[17]"en est la forme courte.
– "/child::article/child::section[position()=3]/ child::soussection[position()=5]"choisit la cinquième soussectionde la troisième section de l’élément document article.
"article/section[3]/soussection[5]"en est la forme courte.
– "child::note[attribute::type=’attention’]"choisit les enfants du nœud de contexte de type note qui ont un attribut type qui a la valeur attention."note[@type=’attention’]"en est la forme courte.
– "child::note[attribute::type=’attention’][position()=3]" choisit le troisième enfant du nœud de contexte qui est de type note et qui a un attribut type qui a la valeur attention.
"note[@type=’attention’][3]"en est la forme courte.
– "child::note[position()=3][attribute::type=’attention’]" choisit le troisième enfant du nœud de contexte s’il est de type note et a un attribut type qui a la valeur attention.
"note[3][@type=’attention’]"en est la forme courte.
– "child::section[child::titre]"choisit les enfants du nœud de contexte qui sont de type section et qui ont un ou plusieurs enfants titre. "section[titre]"en est la forme courte.
– "child::section[child::titre=’Introduction’]"choisit les enfants du nœud de contexte qui sont de type sectionet qui ont un ou plusieurs enfants titre avec une valeur « Introduction».
"section[titre=’Introduction’]"en est la forme courte.
– "child::*[self::section or self::annexe]"choisit les enfants de type section et annexe du nœud de contexte.
– "child::*[self::section or self::annexe][position()=last()]" choisit le dernier enfant de type section ou annexe du nœud de contexte.
– "child::ligne[attribute::couleur and attribute::largeur]" choisit les enfants de type ligne du nœud de contexte qui ont les deux attributs couleur et largeur.
"ligne[@couleur and @largeur]"en est la forme courte.
– "/descendant::para[1]"choisit le premier descendant de type para.
– "/descendant-or-self::node()/child::para[position()=1]" choisit tous les éléments de type para qui sont les premiers enfants para de leur parents. "//para[1]"en est la forme courte.
– "self::node()/descendant-or-self::node()/child::para"choisit tous les éléments descendants de type para du nœud de contexte. ".//para"en est la forme courte.
– "parent::node()/child::titre"choisit tous les enfants de type titre de l’élément parent du nœud de contexte. "../titre"en est la forme courte.
Chaque axe possède un type de nœud principal:
– pour l’axe attribute le type de nœud principal est attribut; – pour l’axe namespace le type de nœud principal est namespace; – pour les autres types d’axe le type de nœud principal est « élément ».
Dans les exemples précédents nous avons implicitement introduit deux autres notions de base de XPath, à savoir la façon de spécifier les tests pour sélectionner un ensemble de nœuds et l’utilisation de prédicats pour qualifier davantage cette sélection.
La sélection est opérée en spécifiant une expression joker (wildcard)en combinaison le cas échéant avec une spécification d’un type de nœud, dont il existe quatre types: comment()(commentaire), text() (texte), processing-instruction(Litéral) (instruction de traitement), node() (type générique).
En particulier, le test nodal child::section choisit les éléments de type section qui sont des enfants du nœud contexte. En l’absence d’un tel élément, l’ensemble videest sélectionné. D’une façon analogue letest nodal attribute::couleurchoisit l’attribut couleur du nœud contexte. Si le nœud contexte ne possède pas un tel attribut l’ensemble vide est sélectionné.
Les expressions prédicats sont spécifiées entre crochets [ ], ce qui donne par exemple: [titre=’Introduction’].
5.1.2. Expressions
Une expression peut être une référence à une variable, une sous-expression, une valeur littérale, un nombre ou un appel de fonction. Des parenthèses peuvent être utilisées pour améliorer la compréhension ou pour guider l’analyse de l’expression.
Pour les appels de fonctions on évalue d’abord leurs arguments en les convertissant au type requis par la fonction, après quoi la fonction concernée est appelée dans la librairiedes fonctions qui fait partie du contexte de l’évaluationde l’expression en lui passant les arguments résultat retourné par la fonction devient la valeur de la sous-expression.
Un chemin de localisation peut également figurer dans une expression. Dans ce cas l’expression retourne l’ensemble des nœuds sélectionnés par le chemin. L’opérateur d’union | combine plusieurs ensembles de nœuds.
La définition formelle de XPath se trouve à l’annexe C. Une liste des fonctions XPath et XSLT est à l’annexe E.
5.2. Introduction au langage XSLT
Unetransformation XSLT —appelée une feuille de style — estunesériederègles pour transformer un arbre source (source tree) XML en un arbre résultant (result tree). La transformation se fait en associant des motifs (patterns) à des modèles (templates) et en les appliquant aux éléments de l’arbre source. Chaque élément dans le fichier source ne peut correspondre qu’à un seul motif dans la feuille de style. Le modèle en question est alors initialisé pour transformer l’élément source en une partie de l’arbre résultant.
L’arbre source et l’arbre résultant sont disjoints et peuvent avoir une structure totalement différente. En effet des éléments de l’arbre source peuvent passer par un filtre, être réordonnés ou une structure arbitraire peut être insérée dans l’arbre résultant.
Comme indiqué ci-dessus une feuille de style contient une série de règles. Chaque règle a deux parties: un motif de correspondance (match pattern) pour sélectionner des éléments dans l’arbre source et un modèle qui sera initialisé pour construire une partie de l’arbre résultant. Cette structure générale permet d’appliquer une même feuille de style à une large classe de documents caractérisés par une arborescence source similaire. Exemple simple:
1 <xsl:template match="emph"> <!-- motif -->
2 <fo:sequence font-style="italic"> <!-- ++++++++++ --> 3 <xsl:apply-templates/> <!-- + modèle + -->
4 </fo:sequence> <!-- ++++++++++ -->
5 </xsl:template>
La ligne un est le motif, qui spécifie que le modèle de traitement des lignes 2–4 est à appliquer aux éléments du document source qui ont un type emph (notons toutefois que certains éléments de type emph peuvent être traités différemment s’ils sont sélectionnés par un motif ayant une priorité plus élevée, voir la section 5.5 de la spécification XSLT[53]).
5.2.1. Structure d’une feuille de style
Ci-dessous suit une liste de tous les éléments qui peuvent être utilisés au niveau supérieur d’une feuille de style XSLT. Les endroits où le contenu ou un attribut doivent être spécifiés sont indiqués par . Il est à souligner qu’une feuille de style peut contenir zéro ou plusieurs éléments des différents types indiqués. À part l’élément <xsl:import >(ligne3),quidoit,s’ilestprésent,précéder touslesautres,l’ordre de spécification des éléments dans une feuille de style n’est pas significative, sauf pour le traitement d’éventuelles conditions d’erreur. Notons que le domaine nominal xsl: (ligne 2) a été choisi pour préfixer tous les éléments XSLT.
1 <?xml version="1.0"?>
2 <xsl:stylesheet xmlns:xsl=";>
3 <xsl:import href=" "/>
4 <xsl:include href=" "/>
5 <xsl:strip-space elements=" "/>
6 <xsl:preserve-space elements=" "/>
7 <xsl:key name=" " match=" " use=" "/>
8 <xsl:functions ns=" "> </xsl:functions>
9 <xsl:attribute-set name=" "> </xsl:attribute-set> 10 <xsl:variable name=" "> </xsl:variable>
11 <xsl:param-variable name=" "> </xsl:param-variable>
12 <xsl:template match=" "> </xsl:template>
13 <xsl:template name=" "> </xsl:template>
14 </xsl:stylesheet>
5.2.2. Modèle de traitement
XSLT interprète undocument XML commeunarbre,c’est-à-dire :deuxfeuillesdestyle ou documents source qui sont décrits par un même arbre seront traités par XSLT de façon identique.
XSLT connaît sept types de nœuds dans un arbre:
– le nœud racine, qui a comme unique descendant le nœud document;
– les nœuds élément, qui correspondent aux éléments dans le source XML. Ils sont dans le même ordre que les balises de début dans le document source. Pour chaque attribut spécifié ou qui a une valeur par défaut un nœud attribut est créé. Un élément vide sans attributs n’a pas de nœuds attachés;
– les nœuds texte, qui contiennent toutes les chaînes de caractères textuels (ne faisant pas partie du balisage). Toutes les données de type caractère qui se suivent sans balisage intermédiaire sont déposées dans un même contenant texte;
– les nœuds attribut, qui contiennent des attributs associés à un élément et sont ainsi toujours attachés à un nœud élément ;
– les nœuds domaine nominal, qui sont construits à partir du document source et de la feuille de style;
– les nœuds instructions de traitement (IT) qui sont créés pour chaque instruction de traitement avec un nom égal à la cible de l’IT. Un tel nœud a comme valeur la chaîne de caractères qui définit l’IT;
– les nœuds commentaire qui sont générés pour chaque commentaire dans le fichier source.
À chaque type de nœud est associée une valeur (comme chaîne de caractères). Pour certains types cette valeur fait partie du nœud lui-même, alors que pour d’autres elle est calculée à partir de la valeur des nœuds des sous-éléments.
6. Exemples de feuilles de style XSL
Cette section contient des exemples de plus en plus complexe montrant l’utilisation des feuilles de style XSL pour transformer les documents XSL et obtenir différentes représentations. Pour bien comprendre les détails il faut se référer aux annexes C (définition du langage XPath), D (définition du langage XSLT) et E (liste des fonctions utilisés avec XPath et XSLT), ainsi qu’aux spécifications XPath[49] et XSLT [53].
6.1. Une invitation sous plusieurs formes
Notre premier exemple est emprunté au LATEX Web Companion[15]. Nous avons décidé d’envoyer une invitation à nos collègues pour leur proposer de se voir quelque part pour faire la fête. Voici la DTD que nous avons choisie pour modéliser l’information:
1 <!-- invitation DTD -->
2 <!ELEMENT invitation (front, body, back) >
3 | <!ELEMENT front | (to, date, where, why?) > |
4 | <!ELEMENT date | (#PCDATA) > |
5 | <!ELEMENT to | (#PCDATA) > |
6 | <!ELEMENT where | (#PCDATA) > |
7 | <!ELEMENT why | (#PCDATA) > |
8 | <!ELEMENT body | (par+) > |
9 | <!ELEMENT par | (#PCDATA|emph)* > |
10 | <!ELEMENT emph | (#PCDATA) > |
11 | <!ELEMENT back | (signature) > |
12 <!ELEMENT signature (#PCDATA) >
Avec ce modèle, qui n’utilise que des éléments pour indiquer le contenu sémantique du document XML, nous balisons le texte (anglais) invitation.xmlsuivant:
1 <?xml version="1.0"?>
2 <!DOCTYPE invitation SYSTEM "">
3 <invitation>
4 <!-- ++++ The header part of the document ++++ -->
5 <front>
6 <to>Anna, Bernard, Didier, Johanna</to>
7 <date>Next Friday Evening at 8 pm</date>
8 <where>The Web Cafe</where>
9 <why>My first XML baby</why>
10 </front>
11 <!-- +++++ The main part of the document +++++ -->
12 <body>
13 <par>I would like to invite you all to celebrate
14 the birth of <emph>Invitation</emph>, my
15 first XML document child.</par>
16 <par>Please do your best to come and join me next Friday 17 evening. And, do not forget to bring your friends.</par>
18 <par>I <emph>really</emph> look forward to see you soon!</par>
19 </body>
20 <!-- +++ The closing part of the document ++++ -->
21 <back>
22 <signature>Michel</signature>
23 </back>
24 </invitation>
À l’aide de ce document nous allons montrer comment cette information peut être transformée en plusieurs formats (HTML, LATEX, objets formatés).
6.1.1. Sortie LATEX
Commençons par transformer le document, en LATEX. Pour cette tâche nous nous basons sur la feuille de style XSL invlat1.xslsuivante:
1 <?xml version=’1.0’?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="text" indent="no" encoding="ISO-8859-1"/>
5
6 <xsl:strip-space elements="*"/>
7
8 <xsl:template match="invitation">
9 <xsl:text>\documentclass[12pt]{article}
10 \usepackage{invitation}
11 \begin{document}
12 </xsl:text>
13 <xsl:apply-templates/>
14 <xsl:text>\end{document}
15 </xsl:text>
16 </xsl:template>
17
18 <xsl:template match="front">
19 <xsl:text>\begin{Front}
20 \To{</xsl:text>
21 <xsl:value-of select="to"/>
22 <xsl:text>}
23 \Date{</xsl:text>
24 <xsl:value-of select="date"/>
25 <xsl:text>}
26 \Where{</xsl:text>
27 <xsl:value-of select="where"/>
28 <xsl:text>}
29 \Why{</xsl:text>
30 <xsl:value-of select="why"/>
31 <xsl:text>}
32 \end{Front}
33 </xsl:text>
34 </xsl:template>
35
36 <xsl:template match="body">
37 <xsl:text>\begin{Body}
38 </xsl:text>
39 <xsl:apply-templates/>
40 <xsl:text>
41 \end{Body}
42 </xsl:text>
43 </xsl:template>
44
45 <xsl:template match="par">
46 <xsl:text>
47 \par </xsl:text>
48 <xsl:apply-templates/>
49 </xsl:template>
50
51 <xsl:template match="emph"> 52 <xsl:text>\emph{</xsl:text>
53 <xsl:apply-templates/>
54 <xsl:text>}</xsl:text>
55 </xsl:template>
56
57 <xsl:template match="back">
58 <xsl:text>\begin{Back}
59 \Signature{</xsl:text>
60 <xsl:value-of select="signature"/>
61 <xsl:text>} 62 \end{Back}
63 </xsl:text>
64 </xsl:template>
65
66 </xsl:stylesheet>
La ligne 2 définit que ce qui suit est une feuille de style XSL qui correspond à la premièreversiondela spécificationet utiliseledomainenominal représenté par xslqui correspond à l’URI un autre URI est spécifié, la feuille de style ne pourra être traitée.
La ligne 4 indique que nous ne désirons pas générer un fichier XML (par défaut) mais un fichier « texte » (method="text").
Pour traiter l’information présente dans un document il existe essentiellement deux approches :
1. « extraction individuelle » (méthode pull) avec sélection de la valeur des éléments à l’aide d’instructions XSLT xsl:value-of.
2. « distribution sélective » (méthode (push) à l’intérieur des motifs de sélection à l’aide d’instructions xsl:apply-templates.
En règle générale, ces deux méthodes sont utilisées dans une même feuille de style. Ainsi, ligne 13, nous « poussons » les éléments contenus à l’intérieur de l’élément invitation(sélectionné par le motif en ligne 8) à travers la feuille de style par l’instruction<xsl:apply-templates/>.Nousfaisonslamêmeopérationàligne39pour l’élément body, en ligne 48 pour les éléments par et en ligne 53 pour les éléments emph.
Par contre,pour lecontenudel’élément front(ligne18),nous allons« tirer»lesdonnées présentes dans les différents éléments en nous servant des instructions de type <xsl:value-of />. Ainsi, ligne 21, nous obtenons la « valeur » (c’est-à-dire : le contenu textuel dans ce cas) de l’élément to qui est un enfant de front, et ainsi de suitepour l’élément date(ligne 24), where(ligne 27) et why(ligne 30). Similairement pour l’élément back, qui est sélectionné par le motif en ligne 57, nous obtenons la valeur de l’élément signatureen ligne 60.
Les autres composantes intéressantes de cette feuille de style sont les commandes LATEX qui sont introduites à l’aide d’instructions <xsl:text> pour chacune des balises XML. Ainsi pour l’élément racine invitation nous écrivons le préambule du document LATEX (lignes 9–11) puis, à la fin (après avoir traité le reste du document grâce à l’instruction XSL <xsl:apply-templates/>de la ligne 13), nous terminons le fichier LATEX avec \end{document}(ligne 14).
Remarquons que chaque balise XML a pratiquement un équivalent en LATEX. C’est le fichier d’extension LATEX (ligne 10) qui interprétera ces balises, comme on peut l’observer dans le fichier source invitation.stysuivant:
1 %
2 % Package to format
3 \setlength{\parskip}{1ex}
4 \setlength{\parindent}{0pt}
5 \pagestyle{empty}%% Turn off page numbering
6 \RequirePackage{array}
7 \newenvironment{Front}%
8 {\begin{center}\huge \sffamily Memorandum\end{center}
9 \begin{flushleft}
10 \begin{tabular}{@{}>{\bfseries}p{.2\linewidth}@{}p{.8\linewidth}@{}}\hline
11 }
12 {To whom: & \@To \\ 13 Occasion: & \@Why \\ 14 Venue: & \@Where \\
15 When: & \@Date \\\hline
16 \end{tabular}
17 \end{flushleft}
18 }
19 \newenvironment{Body}{\vspace*{\parskip}}{\vspace*{\parskip}}
20 \newenvironment{Back} 21 {\begin{flushleft}}
22 {\hspace*{.5\linewidth}\fbox{\emph{\@Sig}}
23 \end{flushleft}
24 }
25 \newcommand{\To}[1]{\gdef\@To{#1}}
26 \newcommand{\Date}[1]{\gdef\@Date{#1}}
27 \newcommand{\Where}[1]{\gdef\@Where{#1}}
28 \newcommand{\Why}[1]{\gdef\@Why{#1}}
29 \newcommand{\Signature}[1]{\gdef\@Sig{#1}}
30 \endinput
Nous avons opté pour une correspondance générique entre les types d’élément XML et leur représentation LATEX. Nous n’avons pas traduit ces éléments directement en constructions élémentaires mais nous avons utilisé des commandes et environnements spécifiques qui « mappent » les noms dans le document source sur un nom LATEX (ainsi l’élément <to> est « mappé » sur la commande \To, etc.). Cette approche
INVITATION To whom: Anna, Bernard, Didier, Johanna Occasion: My first XML baby Venue: The Web Cafe When: Next Friday Evening at 8 pm I would like to invite you all to celebrate the birth of Invitation, my first XML document child. Please do your best to come and join me next Friday evening. And, do not forget to bring your friends. I really look forward to see you soon! From: Michel |
FIGURE 3 – Résultat du formatage d’un document XML avec LATEX
nous permet de généraliser cette extension à d’autres langues (en particulier le français, voir page 41).
La seule chose qui nous manque pour transformer le XML en un autre format est un programme d’analyse qui réalise les recommandations XML et XSL. Il en existe plusieurs, mais dans ce qui suit nous en utilisons uniquement deux, dont le programme xt[5] de James CLARK, un des éditeurs des recommandations de la famille XSL. Il s’agit d’une bibliothèque Java de type jar qui permet de transformer un document XML dans un autre format d’après les règles spécifiées dans une feuille de style XSL.
La commande suivante montre comment utiliser le processeur xt. Nous spécifions lefichier source XML ,la feuilledestyle XSL à l’entrée et nous obtenons le fichier à la sortie. java .Driver
Après compilation du fichier TEX avec LATEX en utilisant l’extension invitation.stynous obtenons le résultat montré à la figure 3.
6.1.2. Sortie HTML
Nous savons déjà que nous pouvons baliser un document XML de plusieurs façons. Dans la première version que nous venons d’étudier, nous avons privilégié l’utilisation de types d’élément distincts pour les différentes parties structurelles de l’information. Une autre possibilité (que nous explorons ci-dessous) spécifie une partie de l’information à l’aide d’attributs, ce qui minimise le nombre de balises. Voici la DTD qui définit la structure du balisage pour cette deuxième version du fichier XML :
1 <!-- invitation2 DTD -->
2 <!ENTITY % i18n "xml:lang NMTOKEN #IMPLIED">
3 <!ELEMENT invitation (par+)>
4 <!ATTLIST invitation %i18n;
5 | date CDATA #REQUIRED | |
6 | to CDATA #REQUIRED | |
7 | signature CDATA #REQUIRED | |
8 | where CDATA #REQUIRED | |
9 | why CDATA #IMPLIED | |
10 | > | |
11 | <!ELEMENT par | (#PCDATA|emph)*> |
12 | <!ELEMENT emph | (#PCDATA)> |
La DTD ne contient plus que trois éléments: invitation (la racine), par et emph. D’après cette DTD nous avons saisi le fichier source XML invitation2.xmlsuivant:
1 <?xml version="1.0"?>
2 <!DOCTYPE invitation SYSTEM "">
3 <invitation to="Anna, Bernard, Didier, Johanna"
4 date="Next Friday Evening at 8 pm"
5 where="The Web Cafe"
6 why="My first XML baby"
7 signature="Michel"
8 >
9 <par>
10 I would like to invite you all to celebrate 11 the birth of <emph>Invitation</emph>, my 12 first XML document child.
13 </par>
14 <par>
15 Please do your best to come and join me next Friday 16 evening. And, do not forget to bring your friends.
17 </par>
18 <par>
19 I <emph>really</emph> look forward to see you soon!
20 </par>
21 </invitation>
Ce fichier invitation2.xmlcontient effectivement la même information que le fichier de la section précédente. En particulier toutes les informations génériques concernant l’invitation (date, to, etc.) sont devenues des attributs de l’élément racine invitation.
Pour transformer le fichier XML invitation2.xmlen HTML nous utilisons le fichier de style XSL invhtml2.xslsuivant:
1 <?xml version=’1.0’?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="html"/>
5 <xsl:preserve-space elements="*"/>
6
7 <xsl:template match="invitation">
8 <html>
9 <head>
10 <title> Invitation (XSL/CSS formatting) </title>
11 <link href="" rel="stylesheet" type="text/css"/>
12 <!-- 12 November 1998 mg -->
13 </head>
14 <body>
15 <h1>INVITATION</h1>
16 <table>
17 <tbody>
18 <tr><td class="front">To: </td>
19 <td><xsl:value-of select="@to"/></td></tr>
20 <tr><td class="front">When: </td>
21 <td><xsl:value-of select="@date"/></td></tr>
22 <tr><td class="front">Venue: </td>
23 <td><xsl:value-of select="@where"/></td></tr>
24 <tr><td class="front">Occasion: </td>
25 <td><xsl:value-of select="@why"/></td></tr>
26 </tbody>
27 </table>
28 <xsl:apply-templates/>
29 <p class="signature"><xsl:value-of select="@signature"/></p>
30 </body>
31 </html>
32 </xsl:template>
33
34 <xsl:template match="par">
35 <p><xsl:apply-templates/></p>
36 </xsl:template>
37
38 <xsl:template match="emph">
39 <em><xsl:apply-templates/></em>
40 </xsl:template>
41
42 </xsl:stylesheet>
La ligne 4 déclare (implicitement) que le domaine nominal par défaut est HTML, ce qui veut dire que chaque balise non qualifiée est considérée comme du HTML. Les motifs des lignes 7, 34 et 42 traitent les trois éléments utilisés dans notre document XML. L’information concernant les destinataires (attribut to), la date (attribut date), etc., est extraite avec des instructions <xsl:value-of /> (lignes 19, 21, etc.). Nous avons utilisé l’élément HTML h1 (ligne 15) pour afficher le titre, alors que l’entête est générée à l’aide d’une table (lignes 16–27) et l’information adéquate (motclé et la valeur correspondante) y est introduite dans les cellules, rangée par rangée. Signalons également que nous utilisons l’attribut class sur plusieurs balises HTML (lignes 19, 21, , 29) pour mieux piloter la représentation dans un butineur à l’aide d’une feuille de style CSS [10, 39, 40] qui permet de contrôler les paramètres de visualisation. La ligne 11 déclare comment associer le fichier HTML avec le fichier CSS invit.csssuivant:
1 /* CSS stylesheet for invitation1 in HTML */
2 BODY {margin-top: 1em; /* global page parameters */
3 margin-bottom: 1em;
4 margin-left: 1em;
5 margin-right: 1em;
6 font-family: serif;
7 line-height: 1.1;
8 color: black;
9 }
10 H1 {text-align: center; /* for global title */
11 font-size: x-large;
12 }
13 P {text-align: justify; /* paragraphs in body */
14 margin-top: 1em;
15 }
16 TABLE { border-width: 0pt }
17 TBODY { border-width: 0pt }
18 TD[class="front"] { /* table data in front matter */
19 text-align: left;
20 font-weight: bold;
21 }
22 TD.front { /* table data in front matter */
23 text-align: left;
24 font-weight: bold;
25 }
26 EM {font-style: italic; /* emphasis in body */
27 }
28 P.signature { /* signature */
29 text-align: right;
30 font-weight: bold;
31 }
Nous obtenons le fichier HTML invhtml2.htmlavec le programme xt avec la commande suivante: xt
La figure 4 montre le résultat HTML visualisé à l’aide du butineur Microsoft Explorer en utilisant la feuille de style CSS invit.cssmontré ci-dessus.
6.1.3. Générer des objets de formatage XSL
Un fichier de style qui traduit le fichier source XML en des objets de formatage XSL est le suivant:
1 <?xml version=’1.0’?>
2 <xsl:stylesheet version="1.0"
3 xmlns:xsl=";
FIGURE 4 – Le fichier HTML visualisé par MS Explorer
4 xmlns:fo=";>
5
6 <xsl:strip-space elements="*"/>
7
8 <!-- Paramétrisations -->
9
10 <xsl:variable name="PageMarginTop">75pt</xsl:variable>
11 <xsl:variable name="PageMarginBottom">125pt</xsl:variable>
12 <xsl:variable name="PageMarginLeft">80pt</xsl:variable>
13 <xsl:variable name="PageMarginRight">150pt</xsl:variable>
14 <xsl:variable name="BodySize">12pt</xsl:variable>
15
16 <xsl:template name="listitem">
17 <xsl:param name="labeltext">labeltext</xsl:param>
18 <xsl:param name="itemid">itemid</xsl:param>
19 <xsl:param name="itemtext">itemtext</xsl:param>
20 <fo:list-item id="{$itemid}">
21 <fo:list-item-label font-style="italic">
22 <fo:block>
23 <xsl:value-of select="$labeltext"/>
24 <xsl:text>:</xsl:text>
25 </fo:block>
26 </fo:list-item-label>
27 <fo:list-item-body>
28 <fo:block><xsl:value-of select="$itemtext"/></fo:block>
29 </fo:list-item-body>
30 </fo:list-item> 31 </xsl:template>
32
33 <xsl:template match=’/’>
34 <fo:root xmlns:fo=";>
35 <fo:layout-master-set>
36 <fo:simple-page-master
37 page-master-name="allpages"
38 margin-top="{$PageMarginTop}"
39 margin-bottom="{$PageMarginBottom}"
40 margin-left="{$PageMarginLeft}"
41 margin-right="{$PageMarginRight}">
42 <fo:region-body margin-bottom="100pt"/>
43 <fo:region-after extent="25pt"/>
44 </fo:simple-page-master>
45 </fo:layout-master-set>
46 <fo:page-sequence>
47 <fo:sequence-specification>
48 <fo:sequence-specifier-repeating
49 page-master-first="allpages"
50 page-master-repeating="allpages"/>
51 </fo:sequence-specification>
52 <fo:flow font-family="serif">
53 <xsl:apply-templates/>
54 </fo:flow>
55 </fo:page-sequence>
56 </fo:root>
57 </xsl:template>
58
59 <xsl:template match="front">
60 <fo:block font-family="sans-serif" font-size="24pt"
61 font-weight="bold" text-align-last="centered"
62 space-after.optimum="24pt">
63 <xsl:text>INVITATION</xsl:text>
64 </fo:block>
65
66 <fo:list-block provisional-distance-between-starts="2cm"
67 provisional-label-separation="6pt">
68 <xsl:call-template name="listitem">
69 <xsl:with-param name="labeltext">To</xsl:with-param>
70 <xsl:with-param name="itemid">listto</xsl:with-param>
71 <xsl:with-param name="itemtext"><xsl:value-of select="to"/></xsl:with-param>
72 </xsl:call-template>
73 <xsl:call-template name="listitem">
74 <xsl:with-param name="labeltext">When</xsl:with-param>
75 <xsl:with-param name="itemid">listdate</xsl:with-param>
76 <xsl:with-param name="itemtext"><xsl:value-of select="date"/></xsl:with-param>
77 </xsl:call-template>
78 <xsl:call-template name="listitem">
79 <xsl:with-param name="labeltext">Venue</xsl:with-param>
80 <xsl:with-param name="itemid">listwhere</xsl:with-param>
81 <xsl:with-param name="itemtext" select="where"/>
82 </xsl:call-template>
83 <xsl:call-template name="listitem">
84 <xsl:with-param name="labeltext">Occasion</xsl:with-param>
85 <xsl:with-param name="itemid">listwhy</xsl:with-param>
86 <xsl:with-param name="itemtext"><xsl:value-of select="why"/></xsl:with-param>
87 </xsl:call-template>
88 </fo:list-block>
89 </xsl:template>
90
91 <xsl:template match="par">
92 <fo:block space-before.optimum="{$BodySize}">
93 <xsl:apply-templates/>
94 </fo:block>
95 </xsl:template>
96
97 <xsl:template match="emph">
98 <fo:inline-sequence font-style="italic">
99 <xsl:apply-templates/>
100 </fo:inline-sequence>
101 </xsl:template>
102
103 <xsl:template match="back">
104 <fo:block space-before.optimum="{$BodySize}"
105 font-weight="bold" text-align-last="end">
106 <xsl:text>From: </xsl:text>
107 <xsl:value-of select="signature"/>
108 </fo:block>
109 </xsl:template>
110
111 </xsl:stylesheet>
Nousn’essaieronspasd’expliquer endétailtoutesleslignesdecettefeuilledestyle(la norme XSLF [52] n’est d’ailleurs pas encore terminée). Nous mentionnons toutefois en ligne 4 la définition du domaine nominal fo, utilisé partout dans le fichier.
Des variables XSL sont définies en lignes 10–14 et utilisées, par exemple, en lignes 38–41.
La définition du « modèle nommé » (named template) listitem se trouve en lignes 16–31. Nous y voyons comment les trois paramètres labeltext (ligne 17), itemid (ligne 18) et itemtext (ligne 19) sont déclarés et comment une valeur par défaut leur est associée. Les valeurs de ces paramètres sont utilisées en lignes 23, 20 et 28, respectivement (la valeur d’un paramètre ou d’une variable est utilisée en faisant précéder son nom par un dollar $ et en entourant le tout d’accolades, comme en ligne 20 avec id="{$itemid}"). Leurs valeurs peuvent être définies quand le modèle nommé listitemest invoqué (lignes 68–72, 73–77, 78–82 et 83–87).
En traitant le fichier source XML invitation.xmlet la feuille de style avec le processeur XSLT xt, nous obtenons un fichier , qui contient une représentation basée sur des objets de formatage XSL. xt
Pour compiler le fichier nous disposons de deux programmes librement accessibles: FOP [34] de James TAUBER et PassiveTEX[29, 30] de Sebastian RAHTZ. Le premier traduit les objets directement en PDF, alors que PassiveTEX utilise pdftex (donc lemoteur formatagedeTEX)pour produirele PDF.Lafigure5montrelerésultat obtenu par ces deux approches.
XSL FOP
XML???FO????PDF
INVITATION
To: Anna, Bernard, Didier, Johanna
When: Next Friday Evening at 8 pm
Venue: The Web Cafe
Occasion: My first XML baby
I would like to invite you all to celebrate the birth of Invitation , my first XML document child.
Please do your best to come and join me next Friday evening. And, do not forget to bring your friends.
I really look forward to see you soon!
From: Michel
XML??XSL?FO?????PassiveTE?X PDF
INVITATION
To: Anna, Bernard, Didier, Johanna
When: Next Friday Evening at 8 pm
Venue: The Web Cafe
Occasion: My first XML baby
I would like to invite you all to celebrate the birth of Invitation, my first XML document child.
Please do your best to come and join me next Friday evening. And, do not forget to bring your friends.
I really look forward to see you soon!
From: Michel
FIGURE 5 – Résultat PDF obtenu avec FOP et avec PassiveTEX
6.1.4. Exemple en français
Jusqu’ici nous avons étudié des exemples XML d’une invitation en anglais. Toutefois, pour une utilisation par des francophones, il est plus commode de baliser le document en français. Un exemple de noms de balises et d’un texte en français se trouve dans le fichier invitationfr.xmlsuivant:
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE invitation SYSTEM "">
3 <invitation>
4 <!-- ++++ Partie entête ++++ -->
5 <entête>
6 <à>Anna, Bernard, Didier, Johanna</à>
7 <date>Vendredi prochain à 20 heures</date>
8 <où>Le Café du Web</où>
9 <pourquoi>Mon premier bébé XML</pourquoi>
10 </entête>
11 <!-- ++++ Partie corps ++++ -->
12 <corps>
13 <par>
14 J’ai le plaisir de vous inviter à la célébration 15 de la naissance d’<emph>Invitation</emph>, mon 16 premier enfant document XML.
17 </par>
18 <par>
19 S’il vous plaît, faites tout votre possible pour me rejoindre 20 vendredi prochain. Et n’oubliez pas d’emmener vos amis.
21 </par>
22 <par>
23 Je me réjouis <emph>vraiment</emph> d’avance de votre présence.
24 </par>
25 </corps>
26 <!-- ++++ Partie finale ++++ -->
27 <fin>
28 <signature>Michel</signature>
29 </fin>
30 </invitation>
La version française de la DTD a la même architecture que son analogue anglais, tout en utilisant des noms francisés. Le contenu du fichier DTD invitationfr.dtdsuit:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?> 2 <!-- DTD invitation (version française) --> 3 <!-- 11 novembre 1998 mg -->
4 <!ELEMENT invitation (entête, corps, fin) >
5 <!ELEMENT entête (à, date, où, pourquoi?) >
6 <!ELEMENT date (#PCDATA) > 7 <!ELEMENT à (#PCDATA) > 8 <!ELEMENT où (#PCDATA) >
9 <!ELEMENT pourquoi (#PCDATA) >
10 <!ELEMENT corps (par+) >
11 <!ELEMENT par (#PCDATA|emph)* >
12 <!ELEMENT emph (#PCDATA) >
13 <!ELEMENT fin (signature) >
14 <!ELEMENT signature (#PCDATA) >
Notons l’utilisation de caractères accentués pour certains noms d’éléments, comme entête,àetoù.Lefichierd’,montréci-dessous, contient les définitions des commandes et environnements qui correspondent aux différentes balises du fichier XML (versions anglaise et française).
1 %
2 % Package to format
3 \setlength{\textwidth}{22pc}
4 \setlength{\parskip}{1ex}
5 \setlength{\parindent}{0pt}
6 \pagestyle{empty}%% Turn off page numbering
7 \RequirePackage{array,calc}
8 \newcommand{\ToTitle}{To whom}
9 \newcommand{\WhyTitle}{Occasion}
10 \newcommand{\WhereTitle}{Venue}
11 \newcommand{\DateTitle}{When}
12 \newcommand{\SignatureTitle}{From}
13 \DeclareOption{francais}{% French text for fixed texts
14 \renewcommand{\ToTitle}{À}
15 \renewcommand{\WhyTitle}{À l’occasion de}
16 \renewcommand{\WhereTitle}{Où}
17 \renewcommand{\DateTitle}{Quand}
18 \renewcommand{\SignatureTitle}{De la part de}}
19 \newenvironment{Front}%
20 {\begin{center}
21 \Huge\sffamily INVITATION
22 \end{center}
23 }
24 {\begin{flushleft}
25 \rule{\linewidth}{1pt}\\[2mm]
26 \begin{tabular}{@{}>{\bfseries}ll@{}}
27 \ToTitle: & \@To \\ 28 \WhyTitle: & \@Why \\ 29 \WhereTitle: & \@Where \\
30 \DateTitle: & \@Date
31 \end{tabular}\\[2mm]
32 \rule{\linewidth}{1pt}
33 \end{flushleft}
34 }
35 \newenvironment{Body}{\vspace*{\parskip}}{\vspace*{\parskip}}
36 \newenvironment{Back} 37 {\begin{flushleft}}
38 {\hspace*{.5\linewidth}\fbox{\SignatureTitle: \emph{\@Sig}}
39 \end{flushleft}
40 }
41 \newcommand{\To}[1]{\gdef\@To{#1}}
42 \newcommand{\Date}[1]{\gdef\@Date{#1}}
43 \newcommand{\Where}[1]{\gdef\@Where{#1}}
44 \newcommand{\Why}[1]{\gdef\@Why{#1}}
45 \newcommand{\Signature}[1]{\gdef\@Sig{#1}}
46
47 \ProcessOptions
48
49 \endinput
Il s’agit d’une généralisation du fichier invitation.styintroduit à la section 6.1.1. Nous y avons introduit une paramétrisation des textes imprimés pour les différentes entrées dans l’en-tête, avec une dépendance del’option francais(lignes 13–18,une généralisation à d’autres langues serait triviale).
Le fichier XSL invlat1fr.xslpour traduire l’invitation en français en LATEX suit:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <!-- -->
3 <xsl:stylesheet version="1.0"
4 xmlns:xsl=";>
5
6 <xsl:output method="text" indent="no" encoding="ISO-8859-1"/>
7
8 <xsl:strip-space elements="*"/>
9
10 <xsl:template match="/">
11 <xsl:text>\documentclass[francais]{article}
12 \usepackage{invitationfr}
13 \usepackage[T1]{fontenc}
14 \begin{document}
15 </xsl:text>
16 <xsl:apply-templates/>
17 <xsl:text>\end{document}
18 </xsl:text>
19 </xsl:template>
20
21 <xsl:template match="entête">
22 <xsl:text>\begin{Front}
23 \To{</xsl:text>
24 <xsl:value-of select="à"/>
25 <xsl:text>}
26 \Date{</xsl:text>
27 <xsl:value-of select="date"/>
28 <xsl:text>}
29 \Where{</xsl:text>
30 <xsl:value-of select="où"/>
31 <xsl:text>}
32 \Why{</xsl:text>
33 <xsl:value-of select="pourquoi"/>
34 <xsl:text>}
35 \end{Front}
36 </xsl:text>
37 </xsl:template>
38
39 <xsl:template match="corps">
40 <xsl:text>\begin{Body}
41 </xsl:text>
42 <xsl:apply-templates/>
43 <xsl:text>\end{Body}
44 </xsl:text>
45 </xsl:template>
46
47 <xsl:template match="par">
48 <xsl:text>\par</xsl:text>
49 <xsl:apply-templates/>
50 </xsl:template>
51
52 <xsl:template match="emph"> 53 <xsl:text>\emph{</xsl:text>
54 <xsl:apply-templates/>
55 <xsl:text>}</xsl:text>
56 </xsl:template>
57
58 <xsl:template match="fin">
59 <xsl:text>\begin{Back}
60 \Signature{</xsl:text>
FIGURE 6 – Résultat du formatage d’une invitation française avec LATEX
61 <xsl:value-of select="signature"/>
62 <xsl:text>} 63 \end{Back}
64 </xsl:text>
65 </xsl:template>
66
67 </xsl:stylesheet>
À l’exception du remplacement des noms d’élément, par leur version française, cette version de la feuille de style est tout à fait identique au fichier écrit à la section 6.1.1.
Après la génération avec xt d’un fichier LATEX à partir du fichier source et de la feuille de style XSL , nous obtenons la présentation de la figure 6.
6.1.5. Alphabets non-latins et documents codés en UTF-8
Nous avons souligné, dans la discussion du langage XML, que celui-ci est véritablement international car basé sur Unicode. Pour voir comment nous pouvons exploiter optimalement cette possibilité nous avons saisi, à l’aide d’un éditeur qui permet l’utilisation du codage UTF-8, un document qui contient du grec, du cyrillique et quelques autres symboles Unicode. Le document source est montré en figure 7 à l’intérieur d’une fenêtre de l’éditeur yudit[32].
Nous reprenons ci-dessous les premières lignes de ce fichier XML.
1 <?xml version="1.0"?>
2 <!DOCTYPE mydoc [
3 <!ELEMENT mydoc (#PCDATA)>
4 <!ENTITY % ISOcyr1 SYSTEM "">
5 %ISOcyr1;
6 ]>
7 <mydoc>
8 <par>The word Russian (Ð?Ñ?Ñ?Ñ?ОÐÿÐ?) in Cyrillic: <br/> 9 Using ISO Cyrillic set:
10 Русский <br/> 11 Using XML Unicode entities:
12 Русский
13 </par>
La ligne 4 définit l’entité paramètre ISOcyr1 qui l’associe au fichier . La ligne 5 est un appel d’entité paramètre, qui indique que toutes les déclarations présentes dans ce fichier sont inclues à cet endroit dans le sous-ensemble interne. Le fichier ISOcyr1.pencontient par exemple les déclarations suivantes:
1 | <!ENTITY rcy | "р"> <!--small er, Cyrillic --> |
2 | <!ENTITY Rcy | "Р"> <!--capital ER, Cyrillic --> |
3 | <!ENTITY scy | "с"> <!--small es, Cyrillic --> |
4 | <!ENTITY Scy | "С"> <!--capital ES, Cyrillic --> |
Ces entités sont référencées en ligne 10 du document source, alors qu’en ligne 12 nous utilisons une représentation hexadécimale équivalente pour ces lettres cyrilliques. La ligne 8 en présente une forme en UTF-8, qui est indéchiffrable telle que, mais qui est lisible en figure 7.
La figure 8 montre la feuille de style XSL qui transforme le fichier source en HTML. À la première ligne, nous déclarons que le fichier de sortie est en HTML et qu’il sera codé en UTF-8. La fin du fichier montre comment nous pouvons sélectionner le texte russe en utilisant une représentation Unicode en appel de caractères ou directement en code UTF-8, comme la puce (•) ou le motif grec (???).
Le résultatfinal dela transformationdufichier source XML delafigure7avec lafeuille de style XSL de la figure 8 en HTML visualisé avec le butineur Netscape est montré en figure 9.
FIGURE 9 – Résultat avec HTML d’un fichier UTF8 avec Netscape
6.2. XML et XSL pour manipuler une base de données
Dans notre discussion de XSL comme langage de style, nous nous sommes intéressés jusqu’ici principalement aux aspects de formatage de l’information dans le but de la visualiser.
Toutefois XSLT, la partie transformation de XSL, peut aussi servir comme base pour manipuler (au sens large) des données[3]. Il n’est pas notre intention de reproduire dansces pagesles nombreusesdiscussionssurla définitiond’unlangaged’interrogation (query language) pour des bases de données XML (un atelier de deux jours a rassemblé une centaine de participants à Boston en décembre 1998 où plus de soixante propositions ont été discutées pour définir un tel langage [42]).
6.2.1. Préparation d’un fichier XML
Pour montrer comment utiliser XSLT avec une base de données, nous avons choisi de partir de la série de tables contenant les noms des pays et de leurs monnaies en plusieurs langues préparée par les services de l’Union européenne (voir l’URL la version française). Cette table est balisée en HTML et a la structure suivante:
1 <TABLE CELLPADDING="5" WIDTH="95%" BORDER="1">
2 <TR VALIGN="TOP" ALIGN="LEFT" BGCOLOR="#FFFF80">
3 <TD WIDTH="5%"><SMALL><B>Code ISO</B><A HREF="#fn2"
4 ONMOUSEOVER="window.status=’norme ISO 3166 ’; return true"
5 ONMOUSEOUT="window.status=’’; return true"><SUP>2</SUP></A></SMALL></TD>
6 <TD WIDTH="11%"><SMALL><B>Forme courte</B></SMALL></TD>
7 <TD WIDTH="16%"><SMALL><B>Forme longue</B></SMALL></TD>
8 <TD WIDTH="11%"><SMALL><B>Capitale</B></SMALL></TD>
9 <TD WIDTH="11%"><SMALL><B>Citoyen ou habitant</B></SMALL></TD>
10 <TD WIDTH="14%"><SMALL><B>Adjectif</B></SMALL></TD>
11 <TD WIDTH="16%"><SMALL><B>Unité monétaire</B></SMALL></TD>
12 <TD WIDTH="5%"><SMALL><B>Code ISO</B><A HREF="#fn3"
13 ONMOUSEOVER="window.status=’norme ISO 4217 ’; return true"
14 ONMOUSEOUT="window.status=’’; return true"><SUP>3</SUP></A></SMALL></TD>
15 <TD WIDTH="11%"><SMALL><B>Subdivision de l’unité
16 monétaire</B></SMALL></TD>
17 </TR>
18 <TR VALIGN="TOP">
19 <TD><SMALL><B>AD</B></SMALL></TD>
20 <TD><SMALL>Andorre</SMALL></TD>
21 <TD><SMALL>la Principauté d’Andorre</SMALL></TD>
22 <TD><SMALL>Andorre-la-Vieille</SMALL></TD>
23 <TD><SMALL>Andorran</SMALL></TD>
24 <TD><SMALL>andorran</SMALL></TD>
25 <TD><SMALL>peseta; franc français</SMALL></TD>
26 <TD><SMALL><B>ESP; FRF</B></SMALL></TD>
27 <TD><SMALL>centimo; centime</SMALL></TD>
28 </TR>
D’abord, pour obtenir un fichier XML qui peut être manipulé avec les applications décrites dans cet article, nous avons traité le fichier HTML ci-dessus avec l’utilitaire tidy[28] qui « normalise » son contenu et le transforme en XML : tidy -asxml -latin1 < >frtable.xhtml
Puis nous avons enlevé toute information non directement liée aux pays et à leurs monnaies en éliminant les embellissements et les notes explicatives. Pour cela nous avonsécritun fichier destyle XSL quifiltretout cequenous considérons comme inutile.
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0"
3 xmlns:xsl=";>
4 <xsl:output method="xml" encoding="ISO-8859-1"/>
5 <xsl:strip-space elements="td"/>
6
7 <xsl:template match="*" priority="-2">
8 <xsl:copy>
9 <xsl:apply-templates/>
10 </xsl:copy>
11 </xsl:template>
12
13 <xsl:template match="sup|a|i">
14 <!-- ignorer contenu -->
15 </xsl:template>
16 <xsl:template match="small|b">
17 <xsl:apply-templates/>
18 </xsl:template>
19
20 </xsl:stylesheet>
Le motif de correspondance générique (ligne 7–11) s’applique à tous les éléments dans le document XML qui n’ont pas de motif explicite spécifié (d’où l’utilisation de la priorité négative). Tous ces éléments sont copiés (en éliminant leur attributs) par l’instruction<xsl:copy>.Ladeuxième partiedelafeuilledestyleéliminelecontenu des éléments sup, a et i (lignes 13–15)et ne retient que l’informationà l’intérieur des éléments small et b, en éliminant leurs balises (lignes 16–18).
Nousutilisonsleprocesseur XSL LotusXSL[18],unautreprocesseur defeuilledestyle XSL, pour générer le fichier ,comme montré ci-dessous.
java .Process -in frtable.xhtml -xsl -out
========= Parsing and preparing ==========
Parsing and init of took 1559 milliseconds
========= Parsing f.xml ==========
Parse of took 563 milliseconds
============================= Transforming via Input XSL
transform took 3860 milliseconds Total time took 4452 milliseconds
XSLProcessor: done
Lefichier frisotab-in.xmlest beaucoup plus simplequel’original HTML et il aune structure XML :
1 <html>
2 <head>
3 <title>Pays et Monnaies</title>
4 </head>
5 <body>
6 <table>
7 <tr>
8 <td>Code ISO</td>
9 <td>Forme courte</td> 10 <td>Forme longue</td>
11 <td>Capitale</td>
12 <td>Citoyen ou habitant</td>
13 <td>Adjectif</td>
14 <td>Unité monétaire</td>
15 <td>Code ISO</td>
16 <td>Subdivision de l’unité monétaire</td> 17 </tr>
18
19 <tr>
20 <td>AD</td>
21 <td>Andorre</td>
22 <td>la Principauté d’Andorre</td>
23 <td>Andorre-la-Vieille</td>
24 <td>Andorran</td>
25 <td>andorran</td>
26 <td>peseta; franc français</td>
27 <td>ESP; FRF</td>
28 <td>centimo; centime</td>
29 </tr>
Maintenant, nous voulons transformer cette table en une base de données où les neuf composantes de l’information (voir lignes 8–16) sont bien étiquetées. En fait nous nous proposons de baliser l’information de deux façons différentes, l’une en nous basant sur neuf éléments distincts et l’autre sur un élément unique mais avec neuf attributs (c’est analogue aux deux instances de l’invitation que nous avons étudiées antérieurement à la section 6.1).
6.2.2. Base de données basée sur les types d’élément
énéréprécédemment ettransformonsle dans une forme exploitable plus facilement comme base de donnée. À cet effet, nous avons écrit la feuille de style isotab1.xslqui suit.
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="xml" encoding="ISO-8859-1"/>
5 <xsl:strip-space elements="*"/>
6
7 <xsl:template match="/html">
8 <xsl:element name="countries">
9 <xsl:text>
10 </xsl:text>
11 <xsl:apply-templates/>
12 </xsl:element>
13 </xsl:template>
14
15 <xsl:template match="*" priority="-2">
16 <xsl:element name="UNKNOWN/INCONNU">
17 <xsl:value-of select="name(.)"/>
18 <xsl:apply-templates/>
19 </xsl:element>
20 </xsl:template>
21
22 <xsl:template match="head|tr">
23 <!-- ignore content --> 24 </xsl:template>
25
26 <xsl:template match="body|table">
27 <xsl:apply-templates/>
28 </xsl:template>
29
30 <xsl:template match="tr[position()>1]" priority="2">
31 <xsl:element name="country">
32 <xsl:text>
</xsl:text>
33 <xsl:apply-templates/>
34 </xsl:element>
35 <xsl:text>
</xsl:text>
36 </xsl:template>
37
38 <xsl:template match="td[1]">
39 <xsl:element name="shortname">
40 <xsl:apply-templates/>
41 </xsl:element><xsl:text>
</xsl:text>
42 </xsl:template>
43
44 <xsl:template match="td[2]">
45 <xsl:element name="fullname">
46 <xsl:apply-templates/>
47 </xsl:element><xsl:text>
</xsl:text>
48 </xsl:template>
49
50 <xsl:template match="td[3]">
51 <xsl:element name="isocountry">
52 <xsl:apply-templates/>
53 </xsl:element><xsl:text>
</xsl:text>
54 </xsl:template>
55
56 <xsl:template match="td[4]">
57 <xsl:element name="capital">
58 <xsl:apply-templates/>
59 </xsl:element><xsl:text>
</xsl:text>
60 </xsl:template>
61
62 <xsl:template match="td[5]">
63 <xsl:element name="citizen">
64 <xsl:apply-templates/>
65 </xsl:element><xsl:text>
</xsl:text>
66 </xsl:template>
67
68 <xsl:template match="td[6]">
69 <xsl:element name="adjective">
70 <xsl:apply-templates/>
71 </xsl:element><xsl:text>
</xsl:text>
72 </xsl:template>
73
74 <xsl:template match="td[7]">
75 <xsl:element name="currency">
76 <xsl:apply-templates/>
77 </xsl:element><xsl:text>
</xsl:text>
78 </xsl:template>
79
80 <xsl:template match="td[8]">
81 <xsl:element name="isocurrency">
82 <xsl:apply-templates/>
83 </xsl:element><xsl:text>
</xsl:text>
84 </xsl:template>
85
86 <xsl:template match="td[9]">
87 <xsl:element name="currensubunit">
88 <xsl:apply-templates/>
89 </xsl:element><xsl:text>
</xsl:text>
90 </xsl:template>
91
92 </xsl:stylesheet>
Nous yvoyonsque l’informationestentourée del’élément racine countries(ouvert et fermé en ligne 8 et 12, respectivement). Les lignes 15–19 sont un garde-fou contre l’information incorrecte (un nom d’élément non reconnu). Les lignes 21–23 spécifient que nous ignorons l’information contenue dans les éléments head et tr (en général), alors que les lignes 25–27 copient le contenu des éléments body et table (sans leurs balises) dans le fichier de sortie. Comme nous balisons explicitement le contenu de chaque colonne de la table, nous n’avons pas besoin de garder l’en-tête de la table (la première ligne tr, lignes 7–17 du fichier ), d’où la condition dans le motif de sélection en ligne 29 qui ne choisit que les lignes plus grandes que deux (les lignes tr sont par défaut ignorées d’après le motif en ligne 21, d’oùla spécificationd’une prioritéégale à deux garantissant que ce modèle remplace celui par défaut pour le motif en question). Nous y ouvrons un élément country en ligne 30 et nous ajoutons des paires <xsl:text><xsl:text>contenant un retour à lalignepour améliorerlalisibilitédufichierdesortie.Toutlerestantdufichiercorrespond aux différents motifs de sélection de la première jusqu’à la neuvième colonne des lignes de la table où le contenu de chaque colonne sera copié dans un élément dont le type est défini par son contenu.
Avec le processeur XSL lotusxsl nous générons le fichier cible .
java .Process -in -xsl -out
========= Parsing and preparing ========== Parsing and init of took 1135 milliseconds
========= Parsing ==========
Parse of took 368 milliseconds
=============================
Transforming via Input XSL
transform took 30245 milliseconds Total time took 30646 milliseconds
XSLProcessor: done
Voici le début du fichier :
1 <countries>
2 <country>
3 <shortname>AD</shortname>
4 <fullname>Andorre</fullname>
5 <isocountry>la Principauté d’Andorre</isocountry>
6 <capital>Andorre-la-Vieille</capital>
7 <citizen>Andorran</citizen>
8 <adjective>andorran</adjective>
9 <currency>peseta; franc français</currency>
10 <isocurrency>ESP; FRF</isocurrency>
11 <currensubunit>centimo; centime</currensubunit>
12 </country>
Nous avons un peu arrangé la représentation ci-dessus pour mieux mettre en évidence la structure du document. Chaque élément de type country possède neuf enfants: shortname, fullname, , qui correspondent aux neuf colonnes dans la table originale.
En section 6.1.1,nous avons expliqué que deux méthodes sont disponibles pour traiter l’information dans un fichier XML, l’extraction individuelle (pull ) à l’aide d’instructions <xsl:value-of /> et la distribution sélective (push) à l’aide d’instructions <apply-templates/>. Ci-dessus nous avons opté pour la deuxième approche. Toutefois nous pouvons obtenir le même fichier XML en sortie en utilisant la première méthode, comme dans le fichier isotab1-bis.xslqui suit:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3 <xsl:output method="xml" encoding="ISO-8859-1"/>
4 <xsl:strip-space elements="*"/>
5
6 <xsl:template match="/html">
7 <xsl:element name="countries">
8 <xsl:text>
9 </xsl:text>
10 <xsl:apply-templates/>
11 </xsl:element>
12 </xsl:template>
13
14 <xsl:template match="*" priority="-2">
15 <xsl:element name="UNKNOWN/INCONNU">
16 <xsl:apply-templates/>
17 </xsl:element>
18 </xsl:template>
19
20 <xsl:template match="head|tr" priority="0">
21 <!-- ignore content --> 22 </xsl:template>
23
24 <xsl:template match="body|table">
25 <xsl:apply-templates/>
26 </xsl:template>
27
28 <xsl:template match="table/tr[position()>1]" priority="2">
29 <xsl:element name="country">
30 <xsl:text>
31 </xsl:text>
32 <xsl:element name="shortname">
33 <xsl:value-of select="td[1]"/>
34 </xsl:element>
35 <xsl:element name="fullname">
36 <xsl:value-of select="td[2]"/>
37 </xsl:element>
38 <xsl:element name="isocountry">
39 <xsl:value-of select="td[3]"/>
40 </xsl:element>
41 <xsl:element name="capital">
42 <xsl:value-of select="td[4]"/>
43 </xsl:element>
44 <xsl:element name="citizen">
45 <xsl:value-of select="td[5]"/>
46 </xsl:element>
47 <xsl:element name="adjective">
48 <xsl:value-of select="td[6]"/>
49 </xsl:element>
50 <xsl:element name="currency">
51 <xsl:value-of select="td[7]"/>
52 </xsl:element>
53 <xsl:element name="isocurrency">
54 <xsl:value-of select="td[8]"/>
55 </xsl:element>
56 <xsl:element name="currensubunit">
57 <xsl:value-of select="td[9]"/>
58 </xsl:element>
59 <xsl:text>
60 </xsl:text>
61 </xsl:element>
62 <xsl:text>
63 </xsl:text>
64 </xsl:template>
65
66 </xsl:stylesheet>
java .Process -in -xsl -out
========= Parsing and preparing ========== Parsing and init of took 1109 milliseconds
========= Parsing ==========
Parse of took 353 milliseconds
=============================
Transforming via Input XSL
transform took 18043 milliseconds Total time took 18427 milliseconds
XSLProcessor: done
Nous avons remplacé le traitement des lignes tr de la table HTML en lignes 29–39 de la feuille , qui utilisait <apply-templates/> (ligne 33) pour pousser les données XML à travers les autres motifs en lignes 41–93 par un seul modèle dans le fichier (lignes 28–64)qui extrait l’informationà mettredans les éléments (voir lignes 33, 36, etc.) à l’aide d’instructions <xsl:value-of />.
6.2.3. Base de données basée sur les attributs
Une deuxième forme de notre base de données n’utilise que le seul type d’élément country pour baliser l’information en la contenant dans des attributs. La feuille de style XSL isotab2.xslqui transforme le fichier source en cette représentation suit:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3 <xsl:output method="xml" encoding="ISO-8859-1"/>
4 <xsl:strip-space elements="*"/>
5
6 <xsl:template match="/html">
7 <xsl:element name="countries">
8 <xsl:text>
9 </xsl:text>
10 <xsl:apply-templates/>
11 </xsl:element>
12 </xsl:template>
13
14 <xsl:template match="*" priority="-2">
15 <xsl:element name="UNKNOWN/INCONNU">
16 <xsl:apply-templates/>
17 </xsl:element>
18 </xsl:template>
19
20 <xsl:template match="head|tr" priority="0">
21 <!-- ignore content --> 22 </xsl:template>
23
24 <xsl:template match="body|table">
25 <xsl:apply-templates/>
26 </xsl:template>
27
28 <xsl:template match="table/tr[position()>1]" priority="2">
29 <xsl:element name="country">
30 <xsl:attribute name="shortname">
31 <xsl:value-of select="td[1]"/>
32 </xsl:attribute>
33 <xsl:attribute name="fullname">
34 <xsl:value-of select="td[2]"/>
35 </xsl:attribute>
36 <xsl:attribute name="isocountry">
37 <xsl:value-of select="td[3]"/>
38 </xsl:attribute>
39 <xsl:attribute name="capital">
40 <xsl:value-of select="td[4]"/>
41 </xsl:attribute>
42 <xsl:attribute name="citizen">
43 <xsl:value-of select="td[5]"/>
44 </xsl:attribute>
45 <xsl:attribute name="adjective">
46 <xsl:value-of select="td[6]"/>
47 </xsl:attribute>
48 <xsl:attribute name="currency">
49 <xsl:value-of select="td[7]"/>
50 </xsl:attribute>
51 <xsl:attribute name="isocurrency">
52 <xsl:value-of select="td[8]"/>
53 </xsl:attribute>
54 <xsl:attribute name="currensubunit">
55 <xsl:value-of select="td[9]"/>
56 </xsl:attribute>
57 </xsl:element>
58 <xsl:text>
59 </xsl:text>
60 </xsl:template>
61
62 </xsl:stylesheet>
Nous voyons que cette feuille de style est assez semblable à qui génère la base de données en utilisant les types d’élément pour saisir l’information. La seule différence est l’emploi de l’instruction<xsl:attribute name=" ">qui crée un attribut au lieu de <xsl:element name=" ">qui crée un élément (comparer les lignes 30–56 dans les fichiers isotab1-bis.xslet ).
En utilisant lotusxsl avec le fichier source nous obtenons la représentation alternative désirée.
java .Process -in -xsl -out
========= Parsing and preparing ========== Parsing and init of took 1125 milliseconds
========= Parsing ==========
Parse of took 354 milliseconds
=============================
Transforming via Input XSL
transform took 18679 milliseconds Total time took 19065 milliseconds
XSLProcessor: done
Voici le début du fichier :
1 <countries>
2 <country shortname="AD"
3 fullname="Andorre"
4 isocountry="la Principauté d’Andorre"
5 capital="Andorre-la-Vieille"
6 citizen="Andorran"
7 adjective="andorran"
8 currency="peseta; franc français"
9 isocurrency="ESP; FRF"
10 currensubunit="centimo; centime"/>
11 </countries>
Ce fichier contient la même information dans les attributs de l’élément country que le fichier dans les éléments contenus dans le même élément country. Remarquons que, pour une transparence totale, les attributs portent les mêmes noms que les types d’élément correspondants.
Avant de montrer comment utiliser cette petite base de données, nous voulons montrer une feuille de style qui permet de transformer une représentation vers l’autre. Ainsi, le fichier transforme la deuxième forme basée sur les attributs dans la première basée sur les types d’élément. Voici son contenu:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="xml" encoding="ISO-8859-1"/>
5
6 <xsl:template match="/">
7 <xsl:element name="countries"><xsl:text>
</xsl:text>
8 <xsl:for-each select="countries/country">
9 <xsl:element name="country"><xsl:text>
</xsl:text>
10 <xsl:apply-templates select="{.}"/> 11 <xsl:element name="shortname">
12 <xsl:value-of select="@shortname"/>
13 </xsl:element>
14 <xsl:element name="fullname">
15 <xsl:value-of select="@fullname"/>
16 </xsl:element>
17 <xsl:element name="isocountry">
18 <xsl:value-of select="@isocountry"/>
19 </xsl:element>
20 <xsl:element name="capital">
21 <xsl:value-of select="@capital"/>
22 </xsl:element>
23 <xsl:element name="citizen">
24 <xsl:value-of select="@citizen"/>
25 </xsl:element>
26 <xsl:element name="adjective">
27 <xsl:value-of select="@adjective"/>
28 </xsl:element>
29 <xsl:element name="currency">
30 <xsl:value-of select="@currency"/>
31 </xsl:element>
32 <xsl:element name="isocurrency">
33 <xsl:value-of select="@isocurrency"/>
34 </xsl:element>
35 <xsl:element name="currensubunit">
36 <xsl:value-of select="@currensubunit"/>
37 </xsl:element><xsl:text>
</xsl:text>
38 </xsl:element><xsl:text>
</xsl:text> 39 </xsl:for-each>
40 </xsl:element><xsl:text>
</xsl:text>
41 </xsl:template>
42
43 </xsl:stylesheet>
Des retours en ligne (<xsl:text>
</xsl:text>, c’est-à-dire : le code littéral 10, A en hexadécimal) sont introduites ici et là pour améliorer la lisibilité du fichier. Nous avons vérifié que nous obtenons bien un fichier identique après traitement par un processeur XSL.
Inversément, nous transformons la première forme dans la deuxième avec le fichier isotab1to2.xslqui suit.
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="xml" encoding="ISO-8859-1"/>
5
6 <xsl:template match="/">
7 <xsl:element name="countries"><xsl:text>
</xsl:text>
8 <xsl:for-each select="countries/country">
9 <xsl:element name="country">
10 <xsl:attribute name="shortname">
11 <xsl:value-of select="shortname"/>
12 </xsl:attribute>
13 <xsl:attribute name="fullname">
14 <xsl:value-of select="fullname"/> 15 </xsl:attribute>
16 <xsl:attribute name="isocountry">
17 <xsl:value-of select="isocountry"/>
18 </xsl:attribute>
19 <xsl:attribute name="capital">
20 <xsl:value-of select="capital"/>
21 </xsl:attribute>
22 <xsl:attribute name="citizen">
23 <xsl:value-of select="citizen"/>
24 </xsl:attribute>
25 <xsl:attribute name="adjective">
26 <xsl:value-of select="adjective"/>
27 </xsl:attribute>
28 <xsl:attribute name="currency">
29 <xsl:value-of select="currency"/>
30 </xsl:attribute>
31 <xsl:attribute name="isocurrency">
32 <xsl:value-of select="isocurrency"/>
33 </xsl:attribute>
34 <xsl:attribute name="currensubunit">
35 <xsl:value-of select="currensubunit"/>
36 </xsl:attribute>
37 </xsl:element><xsl:text>
</xsl:text>
38 </xsl:for-each>
39 </xsl:element><xsl:text>
</xsl:text>
40 </xsl:template>
41
42 </xsl:stylesheet>
Notons le haut degré de symétrie entre ces deux fichiers où à l’intérieur de la boucle for-each (ligne 8–39 dans et 8–38 dans ) où il suffit pratiquement d’interchanger les attributs et les éléments dans les constructeurs (xsl:attribute etxsl:element)et d’ajouter lesigne« @ »dans lesréférences (xsl:value-of).
Évidemment,pourlesfrancophones, nouspouvonstraduirelesnomsdestypesd’élément. Voici une transformation isotab1to1fr.xslde la première forme (utilisant des éléments) qui traduit les noms d’élément de l’anglais en français.
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="xml" encoding="ISO-8859-1"/>
5
6 <xsl:template match="/">
7 <xsl:element name="listeDesPays"><xsl:text>
</xsl:text>
8 <xsl:for-each select="countries/country">
9 <xsl:element name="pays"><xsl:text>
</xsl:text>
10 <xsl:element name="codeISO">
11 <xsl:value-of select="shortname"/>
12 </xsl:element><xsl:text>
</xsl:text>
13 <xsl:element name="nomComplet">
14 <xsl:value-of select="fullname"/>
15 </xsl:element><xsl:text>
</xsl:text>
16 <xsl:element name="nomISO">
17 <xsl:value-of select="isocountry"/>
18 </xsl:element><xsl:text>
</xsl:text>
19 <xsl:element name="capitale">
20 <xsl:value-of select="capital"/>
21 </xsl:element><xsl:text>
</xsl:text>
22 <xsl:element name="citoyen">
23 <xsl:value-of select="citizen"/>
24 </xsl:element><xsl:text>
</xsl:text>
25 <xsl:element name="adjectif">
26 <xsl:value-of select="adjective"/>
27 </xsl:element><xsl:text>
</xsl:text>
28 <xsl:element name="monnaie">
29 <xsl:value-of select="currency"/>
30 </xsl:element><xsl:text>
</xsl:text>
31 <xsl:element name="monnaieCodeISO">
32 <xsl:value-of select="isocurrency"/>
33 </xsl:element><xsl:text>
</xsl:text>
34 <xsl:element name="monnaieSousunité">
35 <xsl:value-of select="currensubunit"/>
36 </xsl:element><xsl:text>
</xsl:text>
37 </xsl:element><xsl:text>
</xsl:text> 38 </xsl:for-each>
39 </xsl:element><xsl:text>
</xsl:text>
40 </xsl:template>
41
42 </xsl:stylesheet>
Nous avons introduit des retours à la ligne (en utilisant des appels numériques de caractères 
)suivant chaque élément pour plus de lisibilitéet nous avons utilisé la notation « chameau » pour le nom des types d’élément. La notation chameau (de l’anglais camel ) est très répandue dans le domaine de la programmation orientée objets. Elle a pour but d’améliorer la lisibilité des codes-sources informatiques en signalant le début de chaque composante d’un mot-clef avec une majuscule.
Notre base de données prend maintenant la forme détaillée ci-dessous. Grâce à la notation chameau et les noms français, le fichier devient facile à lire.
1 <listeDesPays>
2 <pays>
3 <codeISO>AD</codeISO>
4 <nomComplet>Andorre</nomComplet>
5 <nomISO>la Principauté d’Andorre</nomISO>
6 <capitale>Andorre-la-Vieille</capitale>
7 <citoyen>Andorran</citoyen>
8 <adjectif>andorran</adjectif>
9 <monnaie>peseta; franc français</monnaie> 10 <monnaieCodeISO>ESP; FRF</monnaieCodeISO>
11 <monnaieSousInité>centimo; centime</monnaieSousunité>
12 </pays>
6.2.4. Utiliser la base de données
Il est temps maintenant de voir comment nous pouvons utiliser l’information qui se trouve dans notre base de données. Par exemple, si nous voulons obtenir une liste de tous les pays avec leur nom (simple et ISO) et leur capitale nous pouvons utiliser le fichier XSL suivant:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="text" encoding="ISO-8859-1"/>
5
6 <xsl:template match="/listeDesPays">
7 <xsl:for-each select="pays">
8 <xsl:value-of select="nomComplet"/>
9 <xsl:text> (</xsl:text>
10 <xsl:value-of select="nomISO"/>
11 <xsl:text>) et la capitale </xsl:text>
12 <xsl:value-of select="capitale"/>
13 <xsl:text>.
</xsl:text><!-- retour à la ligne -->
14 </xsl:for-each>
15 </xsl:template>
16
17 </xsl:stylesheet>
Nous sélectionnons l’élément racine listeDesPaysen ligne 6. Puis nous commençons une boucle de type for-each. Cette boucle va de la ligne 7 à la ligne 14. Pour chaque élément pays, on extrait son nom complet (ligne 8), suivi d’une parenthèse ouverte (ligne 9), suivi de son nom ISO (ligne 10), suivi de la chaîne de caractère « ) et la capitale » (ligne 11), suivi du nom de la capitale (ligne 12) et on termine avec un retour à la ligne (ligne 13).
Le fichier texte résultant de la transformation commence ainsi:
1 Andorre (la Principauté d’Andorre) et la capitale Andorre-la-Vieille.
2 les Émirats arabes unis (les Émirats arabes unis) et la capitale Abou Dhabi.
3 l’Afghanistan (l’Émirat islamique d’Afghanistan) et la capitale Kaboul.
4 Antigua-et-Barbuda (Antigua-et-Barbuda) et la capitale Saint John’s.
Nous pouvons permuter des entrées, les trier par ordre alphabétique et améliorer le traitement de l’article partitif « de, de la, du, des, l’ ». C’est ce que nous réalisons dans le fichier XSL frisotab1exa2.xslsuivant:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="text" encoding="ISO-8859-1"/>
5
6 <xsl:template match="/listeDesPays">
7 <xsl:for-each select="pays">
8 <xsl:sort select="capitale"/>
9 <xsl:if test="string(capitale) != ’-’">
10 <xsl:value-of select="capitale"/>
11 <xsl:variable name="Nom" select="string(nomComplet)"/>
12 <xsl:choose>
13 <xsl:when test="substring($Nom,1,3) = ’les’">
14 <xsl:text> est la capitale des </xsl:text>
15 <xsl:value-of select="substring-after($Nom,’ ’)"/>
16 </xsl:when>
17 <xsl:when test="substring($Nom,1,3) = ’le ’">
18 <xsl:text> est la capitale du </xsl:text>
19 <xsl:value-of select="substring-after($Nom,’ ’)"/>
20 </xsl:when>
21 <xsl:when test="substring($Nom,1,3) = ’la ’">
22 <xsl:text> est la capitale de </xsl:text>
23 <xsl:value-of select="$Nom"/>
24 </xsl:when>
25 <xsl:when test=’substring($Nom,1,2) = "l'"’>
26 <xsl:text> est la capitale de </xsl:text>
27 <xsl:value-of select="$Nom"/>
28 </xsl:when>
29 <xsl:otherwise>
30 <xsl:variable name="L1" select="substring($Nom,1,1)"/>
31 <xsl:choose>
32 <xsl:when test="$L1 = ’A’ or $L1 = ’E’ or $L1 = ’I’ or
33 $L1 = ’O’ or $L1 = ’U’ or $L1 = ’Y’">
34 <xsl:text> est la capitale de l’</xsl:text>
35 </xsl:when>
36 <xsl:otherwise>
37 <xsl:text> est la capitale de </xsl:text>
38 </xsl:otherwise>
39 </xsl:choose>
40 <xsl:value-of select="$Nom"/>
41 </xsl:otherwise>
42 </xsl:choose>
43 <xsl:text>.
</xsl:text><!-- retour à la ligne -->
44 </xsl:if>
45 </xsl:for-each>
46 </xsl:template>
47
48 </xsl:stylesheet>
Comme avec la feuille de style précédente nous avons une boucle xsl:foreach sur tous les éléments de type pays (lignes 7–45). En ligne 8 nous déclarons vouloir que la sortie soit triée par ordre alphabétique en utilisant le contenu des éléments capitale comme clé de tri. Avant d’aller plus loin, nous rejetons tous les pays qui n’ont pas une valeur adéquate pour leur capitale (test xsl:if de la ligne 9 qui vérifie que la valeur est bien différente d’un tiret ’-’). Une variable Nom est déclarée en ligne 11 et mise égale au contenu de l’élément nomComplet interprété comme une chaîne de caractères.
Nous devonstraiter ensuite les différentscas defigurepour la formede l’articlepartitif (instruction xsl:choose qui couvre les lignes 12–42). Les instructions xsl:when testent la valeur des premiers caractères de la variable Nom qui contient le début de la chaîne de caractères représentant le nom complet du pays. En fonction de ce que nous trouvons, nous générons la forme grammaticalement correcte. Un cas intéressant est la forme « l’ » où nous devons faire attention à bien imbriquer les différentes formes des caractères « ’ » et « " » dans le test pour l’attribut select (voir la ligne 25 qui utilise la représentation décimale de l’apostrophe « ’ »). Ensuite, si nous n’avons pas trouvé d’article, nous nous retrouvons dans la branche xsl:otherwise (lignes 29–41). Ici, nous devons à nouveau distinguer deux cas: le nom commence par une voyelle(test des lignes 32–33)ou pas (branchexsl:otherwisedes lignes 36–38). Cet exemple montre comment XSL permet la génération d’un format de sortie à la demande, en particulier grâce à la possibilité de construire des tests assez complexes.
Le résultat de l’application de cette feuille de style à notre base de données liste les capitales en ordre alphabétique. Le début du fichier résultant suit:
1 Abou Dhabi est la capitale des Émirats arabes unis.
2 Abuja est la capitale du Nigeria.
3 Accra est la capitale du Ghana.
4 Achgabat est la capitale du Turkménistan.
5 Adamstown est la capitale des Iles Pitcairn.
6 Addis-Abeba est la capitale de l’Éthiopie.
7 Alger est la capitale de l’Algérie.
8 Alofi est la capitale de Nioué.
Nous pouvons aussi utiliser notre base de données pour générer du HTML (ou du LATEX). Voici comment générer une table HTML qui montre une liste des monnaies triée alphabétiquement, avec la sous-unité, l’abréviation ISO et le pays où cette monnaie a cours. Pour plus de variété, nous utilisons la deuxième forme de la base de données où l’information est codée dans les attributs. La transformation entre les deux formats s’est faite à l’aide du fichier XSL frisotab1to2.xslsuivant:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl=";>
3
4 <xsl:output method="xml" encoding="ISO-8859-1"/>
5
6 <xsl:template match="listeDesPays">
7 <xsl:copy>
8 <xsl:apply-templates/>
9 </xsl:copy><xsl:text>
</xsl:text>
10 </xsl:template>
11
12 <xsl:template match="pays">
13 <xsl:copy>
14 <xsl:for-each select="*">
15 <xsl:attribute name="{name(.)}"><xsl:value-of select="."/>
16 </xsl:attribute>
17 </xsl:for-each>
18 </xsl:copy>
19 </xsl:template>
20
21 </xsl:stylesheet>
Les lignes 6–10 choisissent l’élément racine listeDesPays et copient à l’aide de l’instruction xsl:copy tout son contenu. Puis pour chaque élément pays (lignes 12–19) nous copions son contenu et nous faisons une boucle sur tous les éléments enfant « * » (lignes 14–17) en générant, ligne 15, un attribut avec le même nom que l’élément en question (name="{name(.)}") avec comme valeur le contenu de ce même élément (<xsl:value-of select="."/>).Ainsi ce fichier est un équivalent plus court du fichier isotab1to2.xslde la section 6.2.3.
Le fichier frisotab2exa3.xslqui construit la table HTML est le suivant:
1 <?xml version=’1.0’ encoding="ISO-8859-1"?>
2 <html xmlns:xsl="; xsl:version="1.0">
3 <body bgcolor="white">
4 <h1>Les monnaies et les pays</h1>
5 <table border="1" rules="rows">
6 <thead>
7 <tr>
8 <td align="center"><b>monnaie</b></td>
9 <td align="center"><b>sous-unité</b></td>
10 <td align="center"><b>code ISO</b></td>
11 <td align="center"><b>pays</b></td>
12 </tr>
13 </thead>
14 <xsl:for-each select="/listeDesPays/pays">
15 <xsl:sort select="@monnaie"/>
16 <xsl:if test="string(@monnaie) != ’-’">
17 <tr>
18 <td><xsl:value-of select="@monnaie"/></td>
19 <td><xsl:value-of select="@monnaieSousunité"/></td>
20 <td align="center"><tt><xsl:value-of select="@monnaieCodeISO"/></tt></td>
21 <td><xsl:value-of select="@nomComplet"/></td>
22 </tr>
23 </xsl:if>
24 </xsl:for-each>
25 </table>
26 </body>
27 </html>
Comme XML est avant tout un langage pour l’internet la spécification XSLT (à sa section 2.3.1)propose une approche simplifiée pour générer un fichier HTML dans le cas où l’arbre résultant peut être généré à l’aide d’un seule modèle qui agit sur l’élément racine. C’est ce que nous avons mis en œuvre dans notre feuille de style, où, ligne 2, nous déclaronsque le domainenominal par défaut est htmlcequi nous permet d’insérer desinstructions HTML sanspré spécifionsletitre (ligne 4) et construisons la première partie de la table (lignes 5–13). Puis commence une boucle de type xsl:foreachsur les élément /listeDesPays/pays(lignes 14– 24). Le résultat de la boucle est trié par ordre alphabétique du contenu de l’attribut monnaie (ligne 15), mais en éliminant les cas où cette valeur serait non-valable (test en ligne 16). Finalement nous composons une ligne de la table (lignes 17–22)en remplissant la première colonne avec le nom de la monnaie (ligne 18), la deuxième avec le nom de sa sous-unité (ligne 19), la troisième avec le code ISO centré et en police chasse fixe (ligne 20)et la quatrième colonne avec le nom complet du pays (ligne 21). La figure 10 montre le résultat HTML.
6.3. Un recueil de poèmes
Dans ce qui précède nous avons traité des fichiers relativement simples. Dans cette section,nousétudionscommentcombinerplusieursfichierssourceàl’entréeetcomment générer plusieurs fichiers à la sortie. Comme fichiers source, nous avons choisi quelques poèmes de Paul Verlaine que nous avons trouvés sur un site français à l’URL .
La communauté XML (ou SGML) a développé plusieurs DTD « standard » pour être utilisées dans leurs domaines respectifs. Mentionnons d’abord Docbook[36, 9], qui est la base du balisage de beaucoup de manuels d’informatique. Pour notre exemple nousnoustournonsplutôtverslesscienceshumaines, oùlafamilledes DTD duprojet « TEI » (Text Encoding Initiative[4, 33]) est très répandue.
FIGURE 10 – Une table montrant monnaies et pays Nous avons balisé quelques poèmes extraits du recueil Poèmes saturniens dans le fichier :
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <div1>
3 <head>Poèmes saturniens (1866)</head>
4 <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
5 <div2>
6 <head><hi rend="ital">Soleils couchants</hi></head>
7 <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
8 <lg type="stanza" org="uniform" sample="complete" part="N">
9 <l>Une aube affaiblie</l>
10 <l>Verse par les champs</l>
11 <l>La mélancolie</l>
12 <l>Des soleils couchants.</l>
13 <l>La mélancolie</l>
14 <l>Berce de doux chants</l>
15 <l>Mon cœur qui s’oublie</l>
16 <l>Aux soleils couchants.</l>
17 <l>Et d’étranges rêves,</l>
18 <l>Comme des soleils</l>
19 <l>Couchants sur les grèves,</l>
20 <l>Fantômes vermeils,</l>
21 <l>Défilent sans trêves,</l>
22 <l>Défilent, pareils</l>
23 <l>À de grands soleils</l>
24 <l>Couchants sur les grèves.</l>
25 </lg>
26 </div2>
27 <!--++++++++++++++++++++++++++++++++ -->
28 <div2>
29 <head><hi rend="ital">Mon rêve familier</hi></head>
30 <lg type="stanza" org="uniform" sample="complete" part="N">
31 <l>Je fais souvent ce rêve étrange et pénétrant</l>
32 <l>D’une femme inconnue, et que j’aime, et qui m’aime,</l> 33 <l>Et qui n’est, chaque fois, ni tout à fait la même</l>
34 <l>Ni tout à fait une autre, et m’aime et me comprend.</l>
35 </lg>
36 <lg>
37 <l>Car elle me comprend, et mon cœur, transparent</l> 38 <l>Pour elle seule, hélas ! cesse d’être un problème</l>
39 <l>Pour elle seule, et les moiteurs de mon front blême,</l>
40 <l>Elle seule les sait rafraîchir, en pleurant.</l>
41 </lg>
42 <lg>
43 <l>Est-elle brune, blonde ou rousse ? ‐ Je l’ignore.</l>
44 <l>Son nom ? Je me souviens qu’il est doux et sonore</l>
45 <l>Comme ceux des aimés que la Vie exila.</l>
46 </lg>
47 <lg>
48 <l>Son regard est pareil au regard des statues,</l>
49 <l>Et, pour sa voix, lointaine, et calme, et grave, elle a</l>
50 <l>L’inflexion des voix chères qui se sont tues.</l>
51 </lg>
52 </div2>
53 <!-- ++++++++++++++++++++++++++++++++++++++ -->
54 <div2>
55 <head><hi rend="ital">Nevermore</hi></head>
56 <lg type="stanza" org="uniform" sample="complete" part="N">
57 <l>Souvenir, souvenir, que me veux-tu ? L’automne</l>
58 <l>Faisait voler la grive à travers l’air atone,</l>
59 <l>Et le soleil dardait un rayon monotone</l>
60 <l>Sur le bois jaunissant où la bise détone.</l>
61 </lg>
62 <lg>
63 <l>Nous étions seul à seule et marchions en rêvant,</l> 64 <l>Elle et moi, les cheveux et la pensée au vent.</l>
65 <l>Soudain, tournant vers moi son regard émouvant :</l>
66 <l>? Quel fut ton plus beau jour ? ? fit sa voix d’or vivant,</l>
67 </lg>
68 <lg>
69 <l>Sa voix douce et sonore, au frais timbre angélique.</l>
70 <l>Un sourire discret lui donna la réplique,</l> 71 <l>Et je baisai sa main blanche, dévotement.</l>
72 </lg>
73 <lg>
74 <l>‐ Ah ! les premières fleurs, qu’elles sont parfumées !</l>
75 <l>Et qu’il bruit avec un murmure charmant</l>
76 <l>Le premier ? oui ? qui sort de lèvres bien-aimées !</l>
77 </lg>
78 </div2>
79 <!-- +++++++++++++++++++++++++++++++++++++ -->
80 <div2>
81 <head><hi rend="ital">Chanson d’automne</hi></head>
82 <lg type="stanza" org="uniform" sample="complete" part="N">
83 <l>Les sanglots longs</l>
84 <l>Des violons</l>
85 <l rend="indent">De l’automne</l>
86 <l>Blessent mon cœur</l> 87 <l>D’une langueur</l>
88 <l rend="indent">Monotone.</l>
89 </lg>
90 <lg>
91 <l>Tout suffocant</l>
92 <l>Et blême, quand</l>
93 <l rend="indent">Sonne l’heure,</l>
94 </lg>
95 <lg>
96 <l>Je me souviens</l>
97 <l>Des jours anciens</l>
98 <l rend="indent">Et je pleure ;</l>
99 </lg>
100 <lg>
101 <l>Et je m’en vais</l> 102 <l>Au vent mauvais</l>
103 <l rend="indent">Qui m’emporte</l>
104 <l>Deçà, delà,</l> 105 <l>Pareil à la</l>
106 <l rend="indent">Feuille morte.</l>
107 </lg>
108 </div2>
109 </div1>
Lerecueil setrouvedansun élément detype div1(lignes 2–109)et chaque poème est à l’intérieur d’un élément de type div2 (lignes 2–26, 28–52, etc.). Le titre d’un poème est saisi dans un élément de type head, où nous voyons également l’élément hi pour spécifier le type de mise en évidence (lignes 6, 29, etc.). Les stances sont délimitées par des éléments lg (ligne 8–25, 30–35, 36–41, ) et les lignes individuelles par les éléments l. Parfois, nous indiquons que nous désirons un renfoncement pour une ligne donnée à l’aide de l’attribut rend (lignes 85, 88, etc.).
Avec ces mêmes conventions, nous avons également saisi quelques poèmes du recueil Fêtes galantes dans le fichier :
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <div1>
3 <head>Fêtes galantes (1869)</head>
4 <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
5 <div2>
6 <head><hi rend="ital">Clair de lune</hi></head>
7 <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
8 <lg type="stanza" org="uniform" sample="complete" part="N">
9 <l>Votre âme est un paysage choisi</l>
10 <l>Que vont charmant masques et bergamasques,</l>
11 <l>Jouant du luth, et dansant, et quasi</l>
12 <l>Tristes sous leurs déguisements fantasques. </l>
13 </lg><lg>
14 <l>Tout en chantant sur le mode mineur</l>
15 <l>L’amour vainqueur et la vie opportune,</l>
16 <l>Ils n’ont pas l’air de croire à leur bonheur</l>
17 <l>Et leur chanson se mêle au clair de lune,</l>
18 </lg><lg>
19 <l>Au calme clair de lune triste et beau,</l>
20 <l>Qui fait rêver les oiseaux dans les arbres </l>
21 <l>Et sangloter d’extase les jets d’eau,</l>
22 <l>Les grands jets d’eau sveltes parmi les marbres.</l>
23 </lg>
24 </div2>
25 <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
26 <div2>
27 <head><hi rend="ital">Les indolents</hi></head>
28 <lg type="stanza" org="uniform" sample="complete" part="N">
29 <l>Bah ! malgré les destins jaloux,</l>
30 <l>Mourons ensemble, voulez-vous ?</l> 31 <l>‐ La proposition est rare.</l>
32 </lg><lg>
33 <l>‐ Le rare est bon. Donc mourons</l>
34 <l>Comme dans les Décamérons.</l>
35 <l>‐ Hi ! Hi ! Hi ! quel amant bizarre !</l>
36 </lg><lg>
37 <l>‐ Bizarre, je ne sais. Amant</l>
38 <l>Irréprochable, assurément.</l>
39 <l>Si vous voulez, mourons ensemble ?</l>
40 </lg><lg>
41 <l>‐ Monsieur, vous raillez mieux encor</l>
42 <l>Que vous n’aimez, et parlez d’or ;</l>
43 <l>Mais taisons-nous, si bon vous semble ! ? </l>
44 </lg><lg>
45 <l>Si bien que ce soir-là Tircis</l>
46 <l>Et Dorimène, à deux assis</l>
47 <l>Non loin de deux sylvains hilares,</l>
48 </lg><lg>
49 <l>Eurent l’inexpiable tort</l>
50 <l>D’ajourner une exquise mort.</l>
51 <l>Hi ! hi ! hi ! les amants bizarres !</l>
52 </lg>
53 </div2>
54 <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
55 <div2>
56 <head><hi rend="ital">Colloque sentimental</hi></head>
57 <lg type="stanza" org="uniform" sample="complete" part="N">
58 <l>Dans le vieux parc solitaire et glacé,</l>
59 <l>Deux formes ont tout à l’heure passé.</l>
60 </lg><lg>
61 <l>Leurs yeux sont morts et leurs lèvres sont molles,</l>
62 <l>Et l’on entend à peine leurs paroles.</l>
63 </lg><lg>
64 <l>Dans le vieux parc solitaire et glacé,</l>
65 <l>Deux spectres ont évoqué le passé.</l>
66 </lg><lg>
67 <l>‐ Te souvient-il de notre extase ancienne ?</l>
68 <l>‐ Pourquoi voulez-vous donc qu’il m’en souvienne ?</l>
69 </lg><lg>
70 <l>‐ Ton cœur bat-il toujours à mon seul nom ?</l>
71 <l>Toujours vois-tu mon âme en rêve ? ‐ Non.</l>
72 </lg><lg>
73 <l>‐ Ah ! les beaux jours de bonheur indicible</l>
74 <l>Où nous joignons nos bouches ! ‐ C’est possible.</l>
75 </lg><lg>
76 <l>‐ Qu’il était bleu, le ciel, et grand, l’espoir !</l>
77 <l>‐ L’espoir a fui, vaincu, vers le ciel noir.</l>
78 </lg><lg>
79 <l>Tels ils marchaient dans les avoines folles,</l>
80 <l>Et la nuit seule entendit leurs paroles.</l>
81 </lg>
82 </div2>
83 </div1>
Nous combinons les deux recueils à l’aide du fichier principal :
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE TEI.2 SYSTEM "" [
3 <!ENTITY dash "‐">
4 <!ENTITY mdash "—">
5 <!ENTITY oelig "œ">
6 <!ENTITY Poèmes-saturniens SYSTEM ""> 7 <!ENTITY Fêtes-galantes SYSTEM "">
8 ]>
9 <TEI.2>
10 <teiHeader type="text" status="new">
11 <fileDesc>
12 <titleStmt>
13 <title>Divers recueils de poèmes</title>
14 <author>Verlaine, Paul</author>
15 <respStmt>
16 <resp>Transcription en code TEI.2</resp>
17 <name>Michel Goossens</name></respStmt>
18 </titleStmt>
19 <publicationStmt>
20 <distributor>Distributed by mg for GUTenberg</distributor>
21 </publicationStmt>
22 <sourceDesc default="NO">
23 <p></p>
24 </sourceDesc> 25 </fileDesc>
26 <profileDesc>
27 <langUsage default="NO">
28 <language id="FR">Français</language>
29 </langUsage>
30 </profileDesc>
31 </teiHeader>
32 <text>
33 <front>
34 <titlePage>
35 <docTitle>
36 <titlePart>Recueil de poèmes de Paul Verlaine</titlePart>
37 </docTitle>
38 <docAuthor>Michel Goossens</docAuthor>
39 <docDate>Octobre 1999</docDate>
40 </titlePage>
41 </front>
42 <body>
43 &Poèmes-saturniens;
44 &Fêtes-galantes;
45 </body>
46 </text>
47 </TEI.2>
Ce fichier définit (lignes 6 et 7) des entités externes pour insérer les deux fichiers sources (ligne 43) et (ligne 44). Nous faisons référence à la DTD XML simplifiée pour la TEI ( en ligne 2). Dans le sous-ensemble interne de la DTD, nous définissons quelques autres entités: les tirets ndash et mdash et, plus important pour le français, la ligature œ, qui, absente du codage ISO-8859-1, ne peut donc être saisie directement. Tout ce qui se trouve à l’intérieur de l’en-tête TEI correspondant à l’élément teiHeader (lignes 10–31) sera ignoré dans notre traitement ultérieur. Ce qui nous intéresse se trouvent dans l’élément text (lignes 32–46).
6.3.1. TEX comme formateur avec PassiveTEX
Sebastian RAHTZ a développé une série de feuilles de style XSL pour transformer les fichiers XML codés d’après la DTD TEI-lite en TEX et HTML[31]. java .Driver
En particulier, nous pouvons traiter le fichier contenant des objets de formatage XSLF avec PassiveTEX[29], une adaptation de TEX également par Sebastian RAHTZ qui génère du PDF. Ainso nous générons un fichier (voir figure 11).
6.3.2. Création d’ une toile de fichiers HTML
Nous nous proposons, à partir des mêmes fichiers XML contentant des poèmes de Verlaine, de créer une toile HTML (un ensemble de fichiers, un par poème, complété d’un fichier principal qui permet d’adresser tous les fichiers individuels à l’aide des liens hypertexte).
Voici le fichier de style XSL htmlsplit.xslqui gère cette transformation.
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE xsl:stylesheet [
3 <!ENTITY nbsp " ">
4 ]>
5 <xsl:stylesheet version="1.0"
Recueil de poèmes de Paul Verlaine Michel Goossens Octobre 1999 1.Poèmes saturniens (1866) 1.1. Soleils couchants Une aube affaiblie Verse par les champs La mélancolie Des soleils couchants. La mélancolie Berce de doux chants Mon cœur qui s’oublie Aux soleils couchants. Et d’étranges rêves, Comme des soleils Couchants sur les grèves, Fantômes vermeils, Défilent sans trêves, Défilent, pareils À de grands soleils Couchants sur les grèves. 1.2. Mon rêve familier Je fais souvent ce rêve étrange et pénétrant D’une femme inconnue, et que j’aime, et qui m’aime, Et qui n’est, chaque fois, ni tout à fait la même Ni tout à fait une autre, et m’aime et me comprend. Car elle me comprend, et mon cœur, transparent Pour elle seule, hélas ! cesse d’être un problème Pour elle seule, et les moiteurs de mon front blême, Elle seule les sait rafraîchir, en pleurant. Est-elle brune, blonde ou rousse ? - Je l’ignore. Son nom ? Je me souviens qu’il est doux et sonore Comme ceux des aimés que la Vie exila. Son regard est pareil au regard des statues, Et, pour sa voix, lointaine, et calme, et grave, elle a L’inflexion des voix chères qui se sont tues. 1.3. Nevermore Souvenir, souvenir, que me veux-tu ? L’automne Faisait voler la grive à travers l’air atone, Et le soleil dardait un rayon monotone Sur le bois jaunissant où la bise détone. Nous étions seul à seule et marchions en rêvant, Elle et moi, les cheveux et la pensée au vent. Soudain, tournant vers moi son regard émouvant : « Quel fut ton plus beau jour ? » fit sa voix d’or vivant, 1 |
- Hi ! Hi ! Hi ! quel amant bizarre ! - Bizarre, je ne sais. Amant Irréprochable, assurément. Si vous voulez, mourons ensemble ? - Monsieur, vous raillez mieux encor Que vous n’aimez, et parlez d’or ; Mais taisons-nous, si bon vous semble ! » Si bien que ce soir-là Tircis Et Dorimène, à deux assis Non loin de deux sylvains hilares, Eurent l’inexpiable tort D’ajourner une exquise mort. Hi ! hi ! hi ! les amants bizarres ! 2.3. Colloque sentimental Dans le vieux parc solitaire et glacé, Deux formes ont tout à l’heure passé. Leurs yeux sont morts et leurs lèvres sont molles, Et l’on entend à peine leurs paroles. Dans le vieux parc solitaire et glacé, Deux spectres ont évoqué le passé. - Te souvient-il de notre extase ancienne ? - Pourquoi voulez-vous donc qu’il m’en souvienne ? - Ton cœur bat-il toujours à mon seul nom ? Toujours vois-tu mon âme en rêve ? - Non. - Ah ! les beaux jours de bonheur indicible Où nous joignons nos bouches ! - C’est possible. - Qu’il était bleu, le ciel, et grand, l’espoir ! - L’espoir a fui, vaincu, vers le ciel noir. Tels ils marchaient dans les avoines folles, Et la nuit seule entendit leurs paroles. 3 |
Sa voix douce et sonore, au frais timbre angélique. Un sourire discret lui donna la réplique, Et je baisai sa main blanche, dévotement. - Ah ! les premières fleurs, qu’elles sont parfumées ! Et qu’il bruit avec un murmure charmant Le premier « oui » qui sort de lèvres bien-aimées ! 1.4. Chanson d’automne Les sanglots longs Des violons De l’automne Blessent mon cœur D’une langueur Monotone. Tout suffocant Et blême, quand Sonne l’heure, Je me souviens Des jours anciens Et je pleure ; Et je m’en vais Au vent mauvais Qui m’emporte Deçà, delà, Pareil à la Feuille morte. 2.Fêtes galantes (1869) 2.1. Clair de lune Votre âme est un paysage choisi Que vont charmant masques et bergamasques, Jouant du luth, et dansant, et quasi Tristes sous leurs déguisements fantasques. Tout en chantant sur le mode mineur L’amour vainqueur et la vie opportune, Ils n’ont pas l’air de croire à leur bonheur Et leur chanson se mêle au clair de lune, Au calme clair de lune triste et beau, Qui fait rêver les oiseaux dans les arbres Et sangloter d’extase les jets d’eau, Les grands jets d’eau sveltes parmi les marbres. 2.2. Les indolents Bah ! malgré les destins jaloux, Mourons ensemble, voulez-vous ? - La proposition est rare. - Le rare est bon. Donc mourons Comme dans les Décamérons. 2 |
FIGURE 11 – Extrait des Poèmes saturniens et des Fêtes galantes de Paul Verlaine.
Cette sortie PDF est générée à partir d’un fichier balisé en XML utilisant la DTD TEI, transformé en objets de formatage par des feuilles de style XSL. Ces objets sont finalement traduits avec PassiveTEX en PDF avec la commande pdftex "&fotex" .
6 xmlns:xsl=";
7 xmlns:date=""
8 xmlns:xt=";
9 extension-element-prefixes="xt">
10
11 <xsl:output method="html" encoding="UTF-8"/>
12
13 <xsl:variable name="MasterFile">verlaine</xsl:variable>
14
15 <!--
16 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17 + Début des définitions des modèles nommées +
18 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19 -->
20
21 <xsl:template name="footer">
22 <hr /><address>
23 Dernière modification : Michel Goossens,
24 <xsl:choose>
25 <xsl:when test="function-available(’date:to-string’) and
26 function-available(’date:new’)">
27 <!-- format date : Fri Dec 31 23:59:59 PDT 1999 --> 28 <!-- 1234567890123456789012345678 -->
29 <xsl:variable name="datetemp" select="date:to-string(date:new())"/>
30 <xsl:variable name="mois" select="substring($datetemp,5,3)"/>
31 <xsl:variable name="jour" select="substring($datetemp,9,2)"/>
32 <xsl:variable name="année" select="substring($datetemp,string-length($datetemp)-3,4)"/>
33 <xsl:variable name="Date" select="concat($jour,’ ’,$mois,’. ’,$année)"/>
34 <xsl:value-of select="$Date"/>
35 </xsl:when>
36 <xsl:otherwise>
37 30 Oct 1999
38 </xsl:otherwise>
39 </xsl:choose>
40 <br />
41 </address>
42 </xsl:template>
43
44 <xsl:template name="header">
45 <xsl:number format="1.1" level="multiple" count="div1|div2"/>.
46 <xsl:value-of select="head"/>
47 </xsl:template>
48
49 <!-- Construction de pointeurs vers le poème suivant and précédent -->
50 <xsl:template name="xrefpanel">
51 <xsl:param name="home"/>
52 <table align="center" rules="none">
53 <tr>
54 <td><a href="{$home}">Monter</a></td>
55 <td><xsl:choose>
56 <xsl:when test="preceding-sibling::div2">
57 <a href="{concat($MasterFile,generate-id(preceding-sibling::div2[1]))}.html">Précédent</a>
58 </xsl:when>
59 <xsl:when test="ancestor::div1/preceding-sibling::div1[1]/div2[last()]">
60 <a href="{concat($MasterFile,generate-id(
61 ancestor::div1/preceding-sibling::div1[1]/div2[last()]))}.html">Précédent</a>
62 </xsl:when>
63 </xsl:choose></td>
64 <td><xsl:choose>
65 <xsl:when test="following-sibling::div2">
66 <a href="{concat($MasterFile,generate-id(following-sibling::div2[1]))}.html">Suivant</a>
67 </xsl:when>
68 <xsl:when test="ancestor::div1/following-sibling::div1[1]/div2[1]">
XML et XSL : un nouveau départ pour le web 71
69 <a href="{concat($MasterFile,generate-id(
70 ancestor::div1/following-sibling::div1[1]/div2[1]))}.html">Suivant</a>
71 </xsl:when>
72 </xsl:choose></td>
73 </tr>
74 </table>
75 <h1><xsl:value-of select="ancestor::div1/head"/></h1>
76 <xsl:variable name="n" select="concat($MasterFile,generate-id())"/>
77 <h2><a name="{$n}"></a><xsl:value-of select="head"/></h2>
78 </xsl:template>
79
80 <!--
81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82 + Début des motifs de séléction pour les éléments +
83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
84 -->
85
86 <xsl:template match="/">
87 <html>
88 <head>
89 <title><xsl:value-of select="//titlePart"/></title>
90 <link rel="stylesheet" type="text/css" href=""/>
91 </head>
92 <body>
93 <h1><xsl:value-of select="//titlePart"/></h1>
94 <h2><xsl:value-of select="//docAuthor"/></h2>
95 <h2><xsl:value-of select="//docDate"/></h2>
96 <xsl:for-each select="//div1">
97 <h3><xsl:call-template name="header"/></h3>
98 <ul>
99 <xsl:for-each select="div2">
100 <xsl:variable name="poemname" select="concat($MasterFile,concat(generate-id()),’.html’)"/>
101 <li><a href="{$poemname}"><xsl:call-template name="header"/></a></li>
102 </xsl:for-each>
103 </ul>
104 </xsl:for-each>
105 <xsl:call-template name="footer"/>
106 </body>
107 </html>
108 <xsl:apply-templates select="//div2"/>
109 </xsl:template>
110
111 <xsl:template match="div2">
112 <xsl:variable name="file" select="concat($MasterFile,concat(generate-id()),’.html’)"/>
113 <xt:document method="html" href="{$file}" encoding="UTF-8">
114 <html>
115 <head>
116 <title><xsl:value-of select="head"/></title>
117 <link rel="stylesheet" type="text/css" href=""/>
118 </head>
119 <body>
120 <xsl:call-template name="xrefpanel">
121 <xsl:with-param name="home" select="concat($MasterFile,’.html’)"/>
122 </xsl:call-template>
123 <xsl:apply-templates/>
124 <xsl:call-template name="footer"/>
125 </body>
126 </html>
127 </xt:document> 128 </xsl:template>
129
130 <xsl:template match="head"> 131 <!-- ignorer le contenu --> 132 </xsl:template>
133
134 <xsl:template match="hi">
135 <xsl:apply-templates/>
136 </xsl:template>
137
138 <xsl:template match="lg">
139 <p><xsl:apply-templates/></p>
140 </xsl:template>
141
142 <xsl:template match="l">
143 <xsl:if test="@rend=’indent’">
144 </xsl:if>
145 <xsl:apply-templates/>
146 <xsl:if test="not(position()=last())">
147 <br /></xsl:if> 148 </xsl:template>
149
150 <xsl:template match="*">
151 <p> ***** Début de l’élément non-prévu </p>
152 <xsl:apply-templates/>
153 <p> Fin de l’élément non-prévu ****** </p>
154 </xsl:template>
155
156 </xsl:stylesheet>
Cette feuille de style XSL est assez complexe et nous allons en examiner les points les plus importants. D’abord la ligne 7 introduit le domaine nominal date et la ligne 8 le domaine nominal xt, qui, de plus, est déclaré comme étant un préfixe d’élément d’extension. Ceci signifie que le code préfixé est une extension du processeur que nous utilisons (xt le cas échéant) et qu’il n’y a aucune garantie que notre feuille de style marche avec un autre processeur (comme lotusxsl), sauf si ce dernier inclut un support pour les mêmes fonctions ou éléments. Les extensions pour les processeurs se trouvent dans leurs documentations respectives (les sections Extension Functions et Multiple Output Documents dans [5] dans notre cas).
Nous utilisons la fonction d’extension pour générer la date (ligne 29), tout en nous assurant avant que les fonctions de date sont bien disponibles (lignes 25–26). Si elles ne le sont pas nous écrivons la chaîne de caractères « 30 Oct 1999 » (ligne 38). Les lignes 29–34 montrent quelques-unes des fonctions pour manipuler les chaînes de caractères (voir la section E pour une liste et un renvoi à la section de la spécification XPathoù elles sont décrites). Ces même lignes montrent également comment utiliser les variables XSL.
Nous avonsmodularisénotre feuillede style XSL en définissantdes modèles nommés (footer en lignes 21–42, header en lignes 44–47 et xrefpanelen lignes 50-76).
En ligne 11, nous déclarons que nous désirons écrire un fichier HTML ; le domaine nominal par défaut sera donc HTML. Ceci nous permet d’introduire les balises HTML sans utiliser de préfixe. Pour traiter correctement les ligatures mdash (—), ndash (–) et oelig (œ) nous choisissons le codage UTF-8.
XML et XSL : un nouveau départ pour le web 73
Le traitement effectif commence avec le modèle pour la racine à la ligne 86. Nous construisonsuntitreglobalenutilisantlabaliseTitlePartdansledocumentsource (ligne89)etintroduisonsunlienversunfichierdestyle CSS (ligne90).
Nous générons le titre pour le corps du document et nous y ajoutons l’auteur et la date du document (lignes 93–95).
Nous effectuons d’abord une boucle for-eachsur les éléments de type div1 (lignes 96–104). À l’intérieur nous appelons d’abord le modèle nommé header (ligne 97), qui génére un numéro de section basé sur les éléments de type div1 déjà rencontrés (ligne 45) puis extrait la valeur de l’élément enfant head de div1 (ligne 46).
Ensuite, nous commençons une liste non-numérotée (ligne 98) qui contient une entrée pour chaque occurrence d’un élément div2 (boucle for-each en lignes 99– 102). Pour un élément de type div2 donné, nous mettons la valeur de la variable poemname(ligne 100)enutilisantla fonctiongenerate-id()qui associeun numéro de référence interne unique au nœud courant. Cette valeur est utilisée à la ligne 101 dansla référence href del’ancredetypea quilielefichier principal (défini par la variable MasterFile en ligne 13) que nous sommes en train d’écrire aux fichiers contenant les poèmes individuels, et dont le nom est construit à partir de cet identificateur unique précédé de la valeur de la variable MasterFile (voir l’attribut select de la ligne 100).
Après avoir traité tous les éléments div1 et div2 nous terminons le fichier principal par un appel au modèle nommé footer (ligne 105). Ce modèle est défini en lignes 21–42 et génère quelques balises HTML avec du texte (lignes 22–23 et 40–41) en y insérant la date (voir ci-dessus pour une discussion de l’utilisation des fonctions d’extension).
Finalement, ligne 108, nous initions la génération des fichiers individuels avec les poèmes en sélectionnant le traitement des éléments de type div2.
Les fichiers avec les poèmes sont générés dans le modèle qui traite le motif div2 (lignes 111–128) et dont le traitement est initié en ligne 118.
Nous commençons (ligne 112) par définir une variable file qui utilisera la même procédure qu’en ligne 100 pour calculer le nom à donner à chaque nœud de type div2 traité. La norme XSLT garantit que chaque nœud dans l’arborescence du document complet aunidentificateur uniquegénéré à l’aidedela fonctiongenerate-id, ainsi nous sommes certains que les noms obtenus en ligne 100 et ici pour nommer les fichiers via la variable file seront identiques.
La ligne 113 crée un document HTML ayant un nom donné par la valeur de la variable file définie en ligne précédente et utilise la codage UTF-8. La possibilité de créer des fichiers étant une extension propre à xt, nous utilisons le domaine nominal xt: défini en ligne 8 pour l’élément xt:document(lignes 113 et 127).
Le reste de la construction des fichiers contenant un poème est assez facile. La ligne 116génère un titrepour l’en-tête HTML. La partiela plus intéressanteest en ligne120, où nous faisons appel au modèle nommé xref. Elle est définie en lignes 49–78. Elle a un paramètre home qui donne le nom de la page principale et sa valeur est définie en ligne 121 en utilisant la valeur de la variable MasterFile.
Le modèle nommé xrefpanel utilise une table pour mettre à la tête de chaque fichier des liens qui permettent à l’utilisateur de naviguer d’un fichier au précédent, au suivant et de remonter au fichier principal. Cette dernière possibilité est facile à traiter puisque le fichier principal est trivial à adresser (ligne 54). Par contre lorsque nous nous trouvons au début de la séquence div2 ou à sa fin les tests en lignes 56 et 65 ne permettent plus de trouver le précédent, respectivement, le suivant. En effet les axes preceding-sibling et following-sibling, qui trouvent des nœuds au même niveau que l’élément courant, ne peuvent sortir de l’élément parent. Il nous faut des tests un peu plus complexes, c’est-à-dire : nous devons sauter d’un élément div1 à un autre pour s’assurer que nous trouvons bien toujours tous les types d’élément précédent ou suivant. C’est ce que nous faisons dans les lignes 60– 61 et 69–70. Par exemple, en ligne 61 nous savons (par le test de la ligne 56) que nous n’avons plus d’élément div2 précédent l’élément courant à l’intérieur de l’élément div1 qui est l’ancêtre de l’élément courant. Donc nous devons d’abord monter d’un niveau pour trouver un élément de type div1 (ancestor::div1). Puis nous choisissons parmi les nœuds de type div1 précèdents le nœud ancêtre le plus proche (preceding-sibling::div1[1]). Pour ce nœud nous sélectionnons le dernier de ses enfants de type div2 (/div2[last()]).C’est ce nœud, s’il existe, qui détermine l’adresse du fichier précédent dans le fichier HTML pour l’élément div2 courant. La même logique (dans la direction opposée following)s’applique pour déterminer si un élément suivant existe au-delà de l’ancêtre div1 de l’élément courant.
Finalement en ligne 77 nous définissons la cible de l’ancre et nous écrivons le titreen sélectionnant la valeur de l’élément head à l’intérieur de div2.
Nous retournons en ligne 123 qui envoie le texte du poème pour traitement par les autres modèles (lignes 130–148). Finalement chaque fichier aura une partie adresse avec la date, etc. générée à l’aide du modèle nommé footer déjà mentionné.
Le résultat de l’application de la feuille de style au fichier source
XML est montré à la figure 12. Nous y montrons les hyperliens présents dans ledocument principal par des flèches. Deplus chacun des sept fichiers avec les poèmes individuels contient des liens vers le poème précédent et suivant et pour remonter au fichier principal. Ces liens sont mis en évidence par des étiquettes Monter, Précédentet Suivant à la première ligne de chaque fichier (sauf aux deux extrémités). Nous avons entré la commande: java .Driver
7. Autres normes W3C basées sur XML
XML est la norme de base qui permet de définir d’autres applications dans plusieurs domaines d’activité. Parmi les plus intéressantes pour nous, signalons:
– XLink [47]: les liens généralisés;
– XPointer[49]: l’adressage généralisé;
– SVG[43]: les graphiques vectoriels ajustables;
– XHTML [44, 45]: un langage HTML modulaire;
– XML Schema[50, 51]: une description des structures et types de données.
Nous allons regarder quelques-uns plus de détails. Il faut savoir toutefois qu’aucun de ces travaux n’est actuellement finalisé et ce qui suit ne correspondra peut-être pas à 100% à la syntaxe qui sera finalement adoptée.
7.1. Modèle XLink pour définir des hyperliens
XLink [47] et XPointer[49] proposent une structure généralisée, efficace et compacte pour représenter des liens internes ou externes à un document. XLink se limite à la définition abstraite des ressources, unités d’information ou de service adressables par un lien, laissant les détails de présentation aux fichiers de styles ou autres mécanismes semblables.
XLink et XPointer se sont inspirés de trois normes existantes:
HTML: définit plusieurs éléments pour gérer les liens et généralise l’utilisation de la notion d’URL (Uniform Resource Locator) qui pointe en majeure partie vers des objets globaux, même si un certain adressage interne est possible (association d’un identificateur à un élément, régions dans des images graphiques);
Hytime: (Hypermedia Time-based Structuring Language) est une application SGML normalisée par l’ISO[37] qui propose un formalisme standardisé pour exprimer des liens entre textes et objets multimedia (images, son, etc.), pour localiser de façon dynamique dans le temps et l’espace les éléments liés, pour accéder aux propriétés de chaque ressource (« ancre » dans la terminologie de HTML) et pour donner un aperçu de la ressource en question (résumé textuel, extrait sonore, image d’un film, etc.);
TEI: (Text Encoding Initiative) est une application SGML développée par plusieurs associations des sciences humaines[4, 33]. Dans le domaine de l’hypertexte il définit une syntaxe formelle pour spécifier la location de données structurées, graphiques et autres types de données, et propose des structures pour créer des liens et des collections de liens à partir de ces ressources.
Un lien exprime une relation entre des ressources. Une ressource peut être n’importe quelle location qui est adressée par le lien. Notons que la nature exacte de la relation entre ces différentes ressources dépend de l’application qui traite le lien ainsi que de l’information sémantique fournie par l’utilisateur.
XLink compte plusieurs types de liens. XPointer, qui est basé sur XPath et s’inspirede l’initiative TEI introduit des méthodes sophistiquées pour localiser les ressources.
Pour permettre aux applications de reconnaître les liens, on définit des éléments et attributs dans le domaine nominal de XLink, par exemple :
1 <A xmlns:xlink="; xlink:type="simple" 2 xlink:href="" xlink:role="liste des pays"
3 xlink:title="Liste des pays" xlink:show="new" xlink:actuate="user">
4 Liste des pays (à jour au 22 octobre 1999)
5 </A>
En fait, cet élément A correspond à l’ancre HTML. Si nous nous trouvons à l’intérieur du domaine nominal xlink, nous pouvons déclarer un lien similaire par une définition simplifiée:
1 <xlink:simple href="" role="liste des pays"
2 title="Liste des pays" show="new" actuate="user">
3 Liste des pays (à jour au 22 octobre 1999)
4 </xlink:simple>
Tout élément peut être transformé en un lien en utilisant l’attribut xlink:type.
7.1.1. Attributs
XLink permet de caractériser les différentes composantes d’un lien à l’aide d’attributs:
href URI identifiant une ressource;
from chaîne de caractères (par exemple un attribut de type ID) identifiant la ressource qui a activé le lien;
to chaîne de caractères (par exemple un attribut de type ID) identifiant la ressource qui est la destinationdu lien; fromet to sont les deux extrémités d’un arc;
show comportement de la ressource pointée; il existe trois options:
new montrer la ressource pointée dans une nouvelle fenêtre en lais-
sant le contexte actuel intact;
parsed intégrer le contenu de la ressource pointée dans le document actuel en l’interprétant comme du XML ;
replace remplacerlecontexteactuel aveclecontenu dela ressourcepointée (c’est ce qui s’utilisele plus souvent sur la toile actuellement);
actuate initialisation du lien; il existe deux options:
user le lien doit être traversé uniquement quand une requête explicite est reçue par l’application (ce comportement est celui de HTML où vous devez cliquer explicitement sur un lien avec la souris pour l’activer);
auto l’application traversera le lien automatiquement quand elle croit que l’utilisateur l’a atteint (par exemple si le pointeur passe par dessus); role attribut sémantique qui décrit à l’aide d’une chaîne de caractères son rôle générique (sa « signification », p.ex. poème); toutes les ressources qui participent à un lien peuvent être caractérisées par leur propre rôle;
title texte décrivant le lien en question.
Cette description permet de mieux comprendre l’exemple du lien simple donné auparavant.
7.1.2. Différents éléments de type link Il existe plusieurs types de liens:
Liens simples
Un lien simple ressemble beaucoup aux éléments A de HTML ou XREF du projet TEI. Un exemple de la définition d’un lien simple et de son utilisation suivent:
<!ELEMENT xlink:simple ANY> <!ATTLIST xlink:simple | |
href CDATA | #REQUIRED |
role CDATA | #IMPLIED |
title CDATA | #IMPLIED |
show (new|parsed|replace) | "replace" |
actuate (user|auto) | "user" |
>
Pour transformer un élément arbitraire en lien simple on déclare:
<!ELEMENT listePays ANY>
<!ATTLIST listePays
xmlns:xlink | CDATA #FIXED "; |
xlink:type | (simple|extended|locator|arc) #FIXED "simple" |
xlink:href | CDATA #REQUIRED |
xlink:role | CDATA #IMPLIED |
xlink:title | CDATA #IMPLIED |
xlink:show | (new|parsed|replace) "replace" |
xlink:actuate (user|auto) "user"
>
Le lien simple introduit une relation entre deux ressources, le texte contenant le lien en question et sa destination. Pour un lien simple la description de la destination du liensetrouve toujours àl’intérieurdudocumentsource:ils’agitd’unlien« in-line » ou interne.
Un exemple d’utilisation serait le suivant:
Pour les curieux il est intéressant de consulter
<listePays href="" title="Liste des pays" role="liste des pays" xlink:show="new" xlink:actuate="user"> la liste des pays (à jour au 22 octobre 1999).
</listePays>
Liens étendus
Un lien étendu peut mettre en évidence des relations entre n’importe quel nombre de ressources et, de plus, il peut être spécifié dans un document qui ne coïncide avec aucune des ressources(les liens peuvent être « out-of-line» ou externes). Ceci permet de générer des liens pour des supports non-modifiables comme les CDROM ou de filtrer des liens à la demande.
Voici une définition explicite d’un lien étendu:
<!ELEMENT xlink:extended ((xlink:arc | xlink:locator)*)>
<!ATTLIST xlink:extended
role | CDATA | #IMPLIED |
title | CDATA | #IMPLIED |
showdefault | (new|parsed|replace) | #IMPLIED |
actuatedefault | (user|auto) | #IMPLIED > |
Voici une déclaration de lien étendu pour un élément arbitraire:
<!ELEMENT listePays ((xlink:arc | xlink:locator)*)>
<!ATTLIST listePays
xmlns:xlink | CDATA #FIXED "; |
xlink:type | (simple|extended|locator|arc) #FIXED "extended" |
xlink:href | CDATA #REQUIRED |
xlink:role | CDATA #IMPLIED |
xlink:title | CDATA #IMPLIED |
xlink:show | (new|parsed|replace) "replace" |
xlink:actuate (user|auto) "user"
>
Voici deux exemples d’utilisation de ces liens étendus. D’abord, une instance explicite d’un lien de ce type:
<xlink:extended role="liste des pays" title="Liste des pays" showdefault="replace" actuatedefault="user">
</xlink:extended> puis avec un élément déclaré comme un lien étendu:
<listePays xmlns:xlink="; xlink:type="extended" xlink:role="liste des pays" xlink:title="Liste des pays" xlink:showdefault="replace" xlink:actuatedefault="user">
</listePays>
Éléments de localisation
Un « localisateur » (locator) est contenu dans un lien étendu pour permettre la définition des ressources qui participent au lien. La ressource externe est spécifiée à l’aide de l’attribut href. Plusieurs éléments de localisation peuvent être associés à un lien. Chaque ressource externe peut avoir sa propre sémantique par rapport au lien et cette sémantique (les attributs role et title) est spécifiée dans les éléments de localisation.
La déclaration d’un localisateur explicite est la suivante:
<!ELEMENT xlink:locator ANY>
<!ATTLIST xlink:locator
id | ID | #REQUIRED |
href | CDATA | #REQUIRED |
role | CDATA | #IMPLIED |
title | CDATA | #IMPLIED > |
Pour utiliser un élément quelconque comme élément de localisation, on déclare:
<!ELEMENT étudiant ANY>
<!ATTLIST étudiant
xmlns:xlink | CDATA #FIXED "; |
xlink:type | (locator) #FIXED "locator" |
id | ID #REQUIRED |
xlink:href | CDATA #REQUIRED |
xlink:role | CDATA #IMPLIED |
xlink:title | CDATA #IMPLIED |
>
Dans un document, nous pouvons alors écrire:
<xlink:locator href="/poèmes/étudiant/PremierEssai" role="poème" title="devoir numéro 1"/>
Plus simplement, un élément de localisation peut être utilisé comme suit:
<étudiant xmlns:xlink="; xlink:href="PremierEssai">Mon premier poème.</foo>
Éléments de type arc
Un « arc » est contenu dans un lien étendu pour définir comment le traverser. Plusieurs éléments de type arc peuvent être associés à un lien. Les autres attributsde ce type d’élément se comportent comme dans les cas précédents.
La déclaration d’un lien explicite de type arc suit:
<!ELEMENT xlink:arc ANY>
<!ATTLIST xlink:arc
from IDREF #REQUIRED to IDREF #REQUIRED >
Si nous voulons transformer un autre élément en lien étendu de type arc nous pouvons écrire:
<!ELEMENT monArc ANY>
<!ATTLIST monArc
xmlns:xlink | CDATA #FIXED "; |
xlink:type | (arc) #FIXED "arc" |
xlink:from | IDREF #REQUIRED |
xlink:to | IDREF #REQUIRED |
show | (new|parsed|replace) "replace" |
actuate | (user|auto) "user" > |
Voici deux exemples d’utilisation:
<xlink:arc from="étudiant" to="poème" show="parsed" actuate="auto"/>
<monArc xmlns:xlink="; xlink:type="arc" xlink:from="étudiant" xlink:to="professeur" show="new" actuate="user"/>
Groupes de liens étendus
Un groupe de liens étendus est un document XML qui peut contenir une série de liens étendus ou d’autres groupes de liens étendus. Cette facilité est intéressante pour accéder à des ressources adressables à l’aide d’une liste de liens stockée dans un autre document.
Dans ce cas, il est souhaitable d’utiliser un élément de type groupe de liens étendus, un lien étendu spécial, pour y enregistrer une liste de liens vers d’autres documents qui, ensembles, forment un groupe de documents liés entre eux. Chaque document de ce type est identifié par un élément de type document de liens étendus, cas spécial d’élément de localisation.
Des exemples de déclaration de groupe de liens étendus dans un document de liens étendus, montrant les attributs possibles liés à xlink sont donnés ci-après. En particulier, la valeur de l’attribut xlink:typedoit être group ou document,respectivement.
<!ELEMENT xlink:group (xlink:document*)>
<!ATTLIST xlink:group steps CDATA #IMPLIED >
<!ELEMENT xlink:document EMPTY>
<!ATTLIST xlink:document href CDATA #REQUIRED >
<xlink:group steps="2">
<xlink:document href=""/>
</xlink:group>
Puisqu’un groupe deliens étendus peut rediriger une application vers un autredocument,qui peut àsontour contenir d’autresgroupesdeliensétendus,ilestpossiblede se trouver dans une boucle infinie. Ainsi l’attribut steps de type numérique devrait indiquer combien de niveaux de liens seraient à traiter. L’utilisation de cet attribut fort utile n’est pas obligatoire.
7.2. XPointer ou les pointeurs généralisés
Un localisateur pour une ressource consiste habituellement en une référence URI. Pour adresser un fragment de ressource, on peut utiliser un pointeur généralisé de type XPointer.
Pour un document XML, XPointer travaille sur le même arbre qu’XSL et les expressions XPath sont la base de la syntaxe XPointer, qui sélectionne certaines parties de l’arbre, par exemple en indiquant leur relation structurelle par rapport à certains autres nœuds. Des pointeurs de type XPointer peuvent agir de façon itérative en exprimant des sélections multiples en chaîne, chacune agissant sur la partie de l’arbre sélectionnée au stade précédent.
La sélection se fait à l’aide d’axes et de prédicats (comme avec XPath).
Les identificateurs de fragments XPointer existent sous trois formes: deux courtes et une complète:
– par compatibilité avec HTML, la première forme courte utilise seulement le nom simple d’un élément ;
– la deuxième forme courte localise un élément par navigation par étapes à par-tir de l’élément racine en utilisant une séquence de nombres séparés par des signes « / »;
– la forme complète permet d’adresser n’importe quel fragment d’un documentXML. Elle se base directement sur le langage XPath qui a été étendu pour permettre la modélisationde sélections utilisateurs et pour s’assurer qu’une pointeur XPointer retourne une seule partie contiguë d’un document.
Les extensions à XPath sont énumérées brièvement ci-dessous.
– La spécification de règles pour initialiser le contexte d’évaluation.
– Deux nouveaux axes pour modeler le choix utilisateur.
L’axe range::adresseune partied’undocument entreun débutet une fin, par exemple :
"id(’b37’)/range::child[1],following-sibling[2]" sélectionne la région du document allant du premier au troisième élément enfant de l’élément identifié avec l’ID « b37 »
"range::id(’section3.1’)/p[last()-1],id(’section3.3’)/p[2]" sélectionne tout à partirdel’avantdernier paragraphe (p[last()-1])del’élémentayantl’identificateursection3.1jusqu’audeuxièmeparagraphe (p[2]) de l’élément ayant l’identificateur section3.3.
L’axe string::adresse une partie d’un document à l’aide d’une chaîne de caractères, par exemple si l’élément identifié par l’ID « b37 » contenait la chaîne de caractères « Association GUTenberg » le pointeur XPointer
"id(’b37’)/string::5,’’"
localisera le point précédant la cinquième lettre (« c »). Avec le pointeur XPointer
"string::4,’Association GUTenberg’,15,2"
localisera « Te » dans la troisième occurrence de la chaîne de caractères « Association GUTenberg ». Les balises sont ignorées, c’est-à-dire : si le document contenait la chaîne « Association<em>GUTenberg</em>» le pointeur XPointer
"string::1,’ion GUT’,-3,3" localisera « GUT ».
– De nouveaux chemins de localisation.
"/" désigne la ressource complète.
La fonction id() localise l’élément dans la ressource avec un attribut de type id et avec la valeur indiquée. Par exemple:
"id(’b37’)"
La fonction here() permet la localisation du nœud de l’élément qui contient directement un pointeur XPointer (dans le texte ou comme attribut). La fonction origin() permet l’adressage relatif à des liens externes comme ceux définis dans XLink.
– Une nouvelle fonction unique() pour les prédicats. Elle retourne la valeur booléenne « vrai » si la liste courante du nœud contexte contient exactement un nœud.
7.3. SVGou l’adieu àJPEG,GIFetPNG?
SVG[43] (Scalable Vector Graphics ou « graphique vectoriel ajustable») combine les avantages des langages PGML (Precision Graphics Markup Language d’Adobe) et VML (Vector Markup Language de Microsoft) et propose un seul langage « simple » pour inclure des informations graphiques dans les fichiers XML de façon portable.
SVG peut être utilisé dans des fichiers indépendants pour représenter les dessins. Ceux-ci peuvent être créés par des applications spécialisées et inclus dans les pages web par exemple par une référence XPointer. Par ailleurs on peut également inclure directement des fragments SVG dans les sources XML.
Voici un exemple de fichier SVG, qui dessine divers rectangles et ellipses.
1 <?xml version="1.0" standalone="yes"?>
2 <!DOCTYPE svg SYSTEM "" >
3 <svg width="20cm" height="175mm">
4 <g style="stroke:black; fill:none; text-antialiasing:true;stroke-antialiasing:true" > 5 <text x="5" y="25" style="font-size:24">Exemple SVG :
6 rectangles et ellipses</text>
7 <rect x="10" y="50" width="100" height="75" />
8 <rect x="120" y="50" width="100" height="75" style="fill:red" />
9 <rect x="230" y="50" width="100" height="75"
10 style="stroke:lime; stroke-width:6" />
11 <rect x="340" y="50" width="100" height="75"
12 style="stroke:blue; fill:none; stroke-width:3;
13 stroke-dasharray:10 5;stroke-linejoin:miter" />
14 </g>
15 <g style="stroke:none; fill:blue">
16 <rect x="10" y="150" width="100" height="75" rx="40" ry="40" /> 17 <rect x="120" y="150" width="100" height="75" rx="50" ry="50" />
18 <rect x="230" y="150" width="100" height="75" rx="60" ry="60" 19 style="stroke:lime; stroke-width:6" />
20 <rect x="340" y="150" width="100" height="75" rx="70" ry="70"
21 style="stroke:blue; fill:none; stroke-width:3;
22 stroke-dasharray:6 3;stroke-linejoin:miter" />
23 </g>
24 <ellipse cx="60" cy="300" rx="50" ry="40" />
25 <ellipse cx="170" cy="300" rx="50" ry="40" style="fill:red" />
26 <ellipse cx="280" cy="300" rx="50" ry="40"
27 style="stroke:lime; stroke-width:6" />
28 <ellipse cx="390" cy="300" rx="50" ry="40" angle="45" />
29 </svg>
La figure 13 montre le résultat de l’interprétation de ces instructions par un programme de visualisation SVG[19].
Il est certain que le langage SVG va jouer un rôle très important dans le monde internet comme format graphique portable.
7.4. XML Schema: au delà de la DTD
Le but principal de XML est l’échange de données d’une base de données à une autre ouentreune basededonnées et uneautrereprésentation propreà une autreapplication, un document électronique étant considéré comme une forme spécifique d’une base de données. La spécification XML Schema devrait faciliter la mise en œuvre de ces échanges.
La DTD informe le destinataire d’un document quels éléments, entités, etc. le document en question peut contenir sous une forme facile à exploiter par un programme informatique. Grâce aux mots-clés et définitions dans la DTD, un programme d’édition peut analyser un document XML pour y repérer certains éléments ou pour indiquer à l’utilisateur si toute l’information marquée comme obligatoire est bien présente.
Les schémas XML vont plus loin que la DTD dont une des limitations majeures est de ne pas être (pour des raisons de compatibilité SGML) sous forme d’un document XML. Aussi, les nombreux outils XML disponibles sur l’internet ne peuvent être utilisés pour analyser, composer ou déveloper les DTD. Néanmoins, se limiter à réécrire l’information présente dans une DTD en XML ne serait qu’une amélioration mineure. Plus important est la possibilité de pouvoir spécifier le type de données qu’un élément peut contenir ainsi que leurs valeurs possibles[51].
La recommendation XML Schema[50]indique également comment structurer l’information pour combiner des données individuelles en entités ou comment combiner lesdonnées venantdeplusieurs sources.Elleproposeuneapproche structurellepour documenter un Schema à l’aide de commentaires structurés, ce qui permettra aux
FIGURE 13 – Quelques formes graphiques simples dessinées avec SVG
programmes informatiques (p.ex. les éditeurs structurels XML) d’assister l’utilisateur en l’informant des caractéristiques d’un type d’élément. Ces commentaires faciliteront la gestion des différentes versions et mises-à-jour d’un schema. Finalement des principes de conformité garantiront que les schémas venant des différents points du globe pourront fonctionner ensemble.
Conclusions
Dans cet article, nous avons d’abord parlé des problèmes liés au langage HTML. Ensuite, nous avons expliqué pourquoi nous pensons que l’introduction de XML permettra la mise en place d’un environnement sur l’internet véritablement global pour le traitement, l’échange et le stockage de l’information électronique.
Nous avons passé en revue les principales composantes du langage XML en nous basant surtout sur des exemples qui ont mis en évidence comment XML « démocratise » l’internet en permettant à chacun de définir son propre langage grâce aux noms d’attributs et d’éléments faciles à comprendre et à mettre en œuvre. Ainsi les internautes chinois, russes ou français pourront-ils saisir leurs documents en se servant de balises dans leur langue maternelle et être sûrs qu’elles seront adaptées au domaine d’application en question (finance, chimie, biologie, commerce électronique, automobile, etc.).
La deuxième partie de l’article a traité du langage XSL pour transformer les documents XML en plusieurs formats. Nous avons montré comment obtenir une sortie LATEX, d’abord en transformant les éléments XML directement en commandes LATEX équivalentes, ou en se servant d’une transformation en objets de formatage XSL, interprétés alors par PassiveTEX, une version spécifique de moteur TEX, ou FOP, générant du PDF directement. Nous avons également abordé le problème de la génération de fichiers HTML et la création d’une toile d’hyperliens reliant les différentes parties entre elles.
Pour ceux qui sont moins intéressés à la présentation de l’information qu’à sa manipulation, nous avons expliqué comment transformer l’information en plusieurs formes plus adaptées aux bases de données.
Nous espérons que, grâce aux exemples détaillés, chacun pourra utiliser ces techniquespour commencer àdévelopper sespropresfeuillesdestyleetainsipleinement profiter des avantages de la familles des langages extensibles.
Dans les dernières pages nous avons brièvement décrit quelques autres langages. Les deux premiers, XLink et XPointer, définissent des liens hypertextes beaucoup plus flexibles que ceux disponibles en HTML. SVG deviendra sans doute très vite le format graphique préféré de l’internet. XML Schema définit le contenu structurel et les types de données pour une famille de documents XML. Toutefois, il est important de souligner que la normalisation de ces langages n’est pas aussi avancée que XSL, CSS ou le DOM (voir à la page 155 l’article de François ROLE et Philippe VERDRET).
Annexes
La section A présente une DTD qui s’inspire de LATEX et qui permet une traduction facilitée de documents saisis d’après cette DTD en LATEX. De façon plus générale, l’utilisationdecette DTD offreuneapproche quasiautomatiquepour sauvegarderdesdocuments LATEX en XML et ainsi pleinement profiter de tous les outils XML disponibles sur l’internet.
Les sections B à E présentent les règles de productions, instructions et fonctions décrites dans les recommandations des domaines nominaux, XPath et XSLT. Ils permettent de connaître relativement facilement la syntaxe de ces éléments mais pour plus dedétails le lecteur doit évidemment se référer aux textes des recommandations en question.
La section F propose une table avec des équivalents français pour certains termes techniques XML.
Pour information et sans commentaires, la section G montre une version de la feuille de style XSL utilisée pour traduire la norme XML en LATEX.
A. LATEX et XML
A.1. Une DTD pour LATEX
Notre intention est de disposer d’une DTD XML qui permette de modéliser relativement facilement des documents initialement balisés en LATEX. Pour limiter la complexité, nous ne proposons pas une DTD qui englobe toutes les fonctions de LATEX, y compris celles du processeur mathématique de TEX. Nous nous bornons à évoquer l’approche à suivre avec un problème de ce type.
Ci-dessous, nous montrons la DTD qui réalise en large partie les commandes et environnements structurels de LATEX en y ajoutant quelques extensions pour mieux tirer profit des possibilités de XML. Par exemple, nous associons à presquetous leséléments unidentificateur(id enligne3),une classe(class enligne 4), un style (style en ligne 5) et un langage (xml:langen ligne 7), le tout encapsulé à l’entité paramètre basic (ligne 8).
Pour modulariser la feuille de style, nous définissons des entités paramètres pour chaque type de commande ou environnement (lignes 10–27). Il faut aussi remarquer que nous permettons l’extension de cette DTD par l’utilisateur par l’inclusion d’entrées ayant le suffixe .new (p.ex. en ligne 10, etc.). En redéfinissant une de ces entités dans le sous-ensemble interne de la DTD, l’utilisateur peut introduire ses propres éléments dans la structure du document. Un exemple de l’utilisation de ce procédé est dans le fichier (voir page A.1) où en ligne 9 nous introduisons un nouvel élément footnote dans l’entité paramètre . Nous devons aussi déclarer l’élément dans la DTD (voir ligne 10). Il faut évidemment faire attention à ce que le modèle de contenu (la structure de la DTD) reste valable. C’est justement dans ce but que les éléments sont considérés par groupes ettraitéspar desentitésdifférentes.Dansnotrecas,l’entitéinlineregroupe des éléments qui peuvent être utilisés à l’intérieur d’un paragraphe (voir la ligne 19 du fichier minilatex.dtdci-dessous). Nous y voyons également comment la partie extensible (l’entité )est introduiteà l’aided’un appel d’entitéparamètre au bout de la déclaration de l’entité paramètre le reste du fichier, nous reconnaissons facilement l’équivalent XML des commandes et environnements LATEX. Nous mentionnons en particulier l’inclusion de graphiques à l’aide du type d’élément includegraphics, où les attributs déclarés en lignes 95–100 correspondent directement aux arguments de la commande \includegraphics de LATEX[14, 23]. Pour l’environnement tabular de LATEX, nous déclarons un élément tabular qui a un modèle de contenu (lignes 104–116) très proche de la syntaxe LATEX.
1 <!-- : XML version of a subset of LaTeX -->
2 <!-- Most elements have the following attributes -->
3 <!ENTITY % all "id ID #IMPLIED
4 class CDATA #IMPLIED
5 style CDATA #IMPLIED">
6 <!-- Most non-empty elements have this language attribute -->
7 <!ENTITY % i18n "xml:lang NMTOKEN #IMPLIED">
8 <!ENTITY % basic "%all; %i18n;">
9 <!-- Declaration of parameter entities for structuring the DTD -->
10 <!ENTITY % "">
11 <!ENTITY % fontchange "emph|textbf|textsc|textsf|textsl|texttt ;">
12 <!ENTITY % "">
13 <!ENTITY % misc "url|quad|hspace|vspace|includegraphics|tag|ent ;">
14 <!ENTITY % "">
15 <!ENTITY % xref "cite|pageref|ref ;">
16 <!ENTITY % "">
17 <!ENTITY % mathobj "displaymath|inlinemath|equation|eqnarray" >
18 <!ENTITY % "">
19 <!ENTITY % inline "%fontchange;|quote|tabular|%misc;|%xref;|%mathobj; ;">
20 <!ENTITY % "">
21 <!ENTITY % list "lalist|description|enumerate|itemize|bibliography ;">
22 <!ENTITY % "">
23 <!ENTITY % preformat "verbatim|verse ;">
24 <!ENTITY % "">
25 <!ENTITY % likepara "%list;|quotation|align|%preformat; ;">
26 <!ENTITY % "">
27 <!ENTITY % floats "figure|table ;">
28
29 <!-- The top level document declarations -->
30 <!ELEMENT document (frontmatter?,bodymatter,backmatter?)>
31 <!ATTLIST document %i18n;
32 class CDATA "article">
33 <!ELEMENT frontmatter (title,author?,date?,abstract?)>
34 <!ELEMENT bodymatter ((par|%likepara;|%floats;|part|chapter|section)*,appendix*)>
35 <!ELEMENT backmatter (index|glossary)*>
36 <!-- fontchanges -->
37 <!ELEMENT emph (#PCDATA|%inline;)*> 38 <!ELEMENT textbf (#PCDATA|%inline;)*>
39 <!ELEMENT textsc (#PCDATA|%inline;)*>
40 <!ELEMENT textsf (#PCDATA|%inline;)*>
41 <!ELEMENT textsl (#PCDATA|%inline;)*>
42 <!ELEMENT texttt (#PCDATA|%inline;)*>
43 <!-- cross-references -->
44 <!ENTITY % idref "refid IDREF #REQUIRED">
45 <!ELEMENT cite EMPTY>
46 <!ATTLIST cite %idref;> 47 <!ELEMENT pageref EMPTY>
48 <!ATTLIST pageref %idref;> 49 <!ELEMENT ref EMPTY>
50 <!ATTLIST ref %idref;>
51 <!-- quoted material inline and displayed -->
52 | <!ELEMENT quote | (#PCDATA|%inline;|par)*> |
53 | <!ATTLIST quote | %basic;> |
54 | <!ELEMENT quotation | (#PCDATA|%inline;|par)*> |
55 | <!ATTLIST quotation | %basic;> |
56 <!-- lists -->
57 <!ELEMENT description ((term*,item*)+)>
58 <!ATTLIST description %basic;>
59 | <!ELEMENT enumerate | ((term*,item*)+)> |
60 | <!ATTLIST enumerate | %basic;> |
61 | <!ELEMENT itemize | ((term*,item*)+)> |
62 | <!ATTLIST itemize | %basic;> |
63 | <!ELEMENT lalist | ((term*,item*)+)> |
64 | <!ATTLIST lalist | %basic;> |
65 | <!ELEMENT term | (#PCDATA|%inline;)*> |
66 | <!ATTLIST term | %basic;> |
67 | <!ELEMENT item | (#PCDATA|%inline;|par|%likepara;)*> |
68 | <!ATTLIST item | %basic;> |
69 <!ELEMENT bibliography (bibitem)*>
70 <!ATTLIST bibliography %basic;>
71 <!ELEMENT bibitem (#PCDATA|%inline;|par|%likepara;)*>
72 <!ATTLIST bibitem %basic;>
73 <!-- low-level bits and pieces -->
74 <!ELEMENT url EMPTY>
75 <!ATTLIST url name CDATA #REQUIRED>
76 <!ELEMENT quad EMPTY> 77 <!ELEMENT hspace EMPTY>
78 <!ATTLIST hspace dim CDATA #REQUIRED> 79 <!ELEMENT vspace EMPTY>
80 <!ATTLIST vspace dim CDATA #REQUIRED>
81 <!ELEMENT tag (#PCDATA)>
82 <!ELEMENT ent EMPTY>
83 <!ATTLIST ent value CDATA #REQUIRED
84 name CDATA #REQUIRED>
85 <!-- everything that can go into a paragraph -->
86 <!ELEMENT par (#PCDATA|%inline;|%likepara;)*>
87 <!ATTLIST par %basic;>
88 <!-- "floats" and their contents -->
89 <!ELEMENT figure (#PCDATA|par|%inline;|%likepara;|caption)*> 90 <!ATTLIST figure %basic;>
91 <!ELEMENT table (#PCDATA|par|%inline;|%likepara;|caption)*>
92 <!ATTLIST table %basic;>
93 <!ELEMENT includegraphics EMPTY>
94 <!ATTLIST includegraphics %basic;
95 file CDATA #REQUIRED
96 width CDATA #IMPLIED 97 height CDATA #IMPLIED 98 bb CDATA #IMPLIED
99 scale CDATA ".5"
100 angle CDATA #IMPLIED>
101 <!ELEMENT caption (#PCDATA|par|%inline;)*>
102 <!ATTLIST caption %basic;>
103 <!-- tabular material -->
104 <!ELEMENT tabular (hline|row)*>
105 <!ATTLIST tabular %basic;
106 preamble CDATA #REQUIRED
107 width CDATA #IMPLIED
108 border CDATA #IMPLIED>
109 <!ELEMENT row (cell)*>
110 <!ATTLIST row %basic;>
111 <!ELEMENT hline EMPTY>
112 <!ELEMENT cell (#PCDATA|%inline;)*>
113 <!ATTLIST cell %basic;
114 rowspan CDATA "1"
115 colspan CDATA "1"
116 align (left|center|right) "center">
117 <!-- verbatim material -->
118 <!ELEMENT verbatim (#PCDATA)>
119 <!ATTLIST verbatim %basic;
120 xml:space (default|preserve) ’preserve’>
121 <!ELEMENT verse (#PCDATA|%inline;)*>
122 <!ATTLIST verse %basic;
123 xml:space (default|preserve) ’preserve’>
124 <!-- things that go in the frontmatter -->
125 <!ELEMENT newline EMPTY>
126 <!ELEMENT title (#PCDATA|%inline;|thanks|newline)*>
127 <!ATTLIST title %basic;>
128 <!ELEMENT author (#PCDATA|%inline;|name|thanks|inst)*>
129 <!ELEMENT name (#PCDATA|%inline;)*>
130 <!ATTLIST name %basic;>
131 <!ELEMENT thanks (#PCDATA|%inline;|newline)*> 132 <!ATTLIST thanks %basic;>
133 <!ELEMENT inst (#PCDATA|%inline;|newline)*>
134 <!ATTLIST inst %basic;>
135 <!ELEMENT date (#PCDATA)>
136 <!ATTLIST date %basic;> 137 <!ELEMENT abstract (par+)>
138 <!ATTLIST abstract %basic;>
139 <!-- structuring -->
140 | <!ENTITY % sect | "stitle, (par|%likepara;|%floats;)* "> |
141 | <!ELEMENT stitle | (#PCDATA|%inline;)*> |
142 | <!ATTLIST stitle | %basic;> |
143 | <!ELEMENT part | (%sect;, (chapter|section|subsection|subsubsection)*)> |
144 | <!ATTLIST part | %basic;> |
145 | <!ELEMENT chapter | (%sect;, section*)> |
146 | <!ATTLIST chapter | %basic;> |
147 | <!ELEMENT section | (%sect;, subsection*)> |
148 | <!ATTLIST section | %basic;> |
149 | <!ELEMENT subsection | (%sect;, subsubsection*)> |
150 | <!ATTLIST subsection | %basic;> |
151 <!ELEMENT subsubsection (%sect;, paragraph*)>
152 <!ATTLIST subsubsection %basic;>
153 <!ELEMENT paragraph (%sect;, subparagraph*)>
154 <!ATTLIST paragraph %basic;> 155 <!ELEMENT subparagraph (%sect;)> 156 <!ATTLIST subparagraph %basic;>
157 <!ELEMENT appendix EMPTY>
158 <!-- backmatter: index and glossary -->
159 <!ELEMENT index (par|%likepara;)*>
160 <!ATTLIST index %basic;>
161 <!ELEMENT glossary (par|%likepara;)*>
162 <!ATTLIST glossagry %basic;>
163 <!-- LaTeX math constructs -->
164 <!ENTITY % LaTeXmath "INCLUDE">
165 <!ENTITY % SYSTEM "">
166 <![ %LaTeXmath; [
167 ;
168 ]]>
169 <!ENTITY % MathML "IGNORE">
170 <!ENTITY % SYSTEM "">
171 <![ %MathML; [
172 ;
173 ]]>
174 <!-- Basic XML entities -->
175 <!ENTITY lt "<"> <!-- "<" -->
176 <!ENTITY gt ">"> <!-- ">" -->
177 <!ENTITY amp "&"> <!-- "&" --> 178 <!ENTITY apos "'"> <!-- "’" -->
179 <!ENTITY quot """> <!-- ’"’ -->
Nous avons pris soin de ne pas lier cette DTD directement à un balisage des mathématiques en utilisant le formalisme de TEX, mais nous avons laissé la porte ouverte à un balisage en MathML (lignes 162–168 pour LATEX, 169–173 pour MathML). Le choix entre les deux syntaxes est géré par la valeur des entités paramètres LaTeXmath (défaut INCLUDE, voir ligne 164) et MathML (défaut IGNORE, voir ligne 169). C’est la valeur de ces deux entités qui décide si les sections conditionnelles qu’elles contrôlent (lignes 166–168 pour LaTeXmath et lignes 171–173 pour MathML) seront incluses ou pas.
Nous avons défini deux DTD séparées pour traiter ces cas. Voici un premièr fichier DTD latexmath.dtdpour exprimer les structures mathématiques à la TEX:
1 <!-- +++ inline and display math -->
2 <!ELEMENT inlinemath (#PCDATA)> 3 <!ATTLIST inlinemath %all;>
4 <!ELEMENT displaymath (#PCDATA)>
5 <!ATTLIST displaymath %all;>
6 | <!ELEMENT equation | (#PCDATA)> |
7 | <!ATTLIST equation | %all;> |
8 | <!ELEMENT eqnarray | (#PCDATA)> |
9 | <!ATTLIST eqnarray | %all;> |
10 | <!ELEMENT align | (#PCDATA)> |
11 | <!ATTLIST align | %all;> |
L’approche MathML est encapsulée dans la DTD latexmml.dtdsuivante:
1 <!-- -->
2 <!ELEMENT equation (math)*>
3 <!ATTLIST equation %all;>
4 <!ELEMENT displaymath (math)*> 5 <!ELEMENT inlinemath (math)*>
6 <!ELEMENT subeqn (math)*>
7 <!ATTLIST subeqn %all;>
8 <!ELEMENT eqnarray (subeqn)*>
9 <!ATTLIST eqnarray %all;
10 number (yes|no) "yes">
11 <!ELEMENT align (%inline;)*>
12 <!ATTLIST align %all; >
13
14 <!-- ISO and MathML DTDs and entities -->
15 <!--Added Math Symbols: Arrows-->
16 <!ENTITY % SYSTEM ""> 17 <!--Added Math Symbols: Binary Operators-->
18 <!ENTITY % SYSTEM ""> 19 <!--Added Math Symbols: Delimiters-->
20 <!ENTITY % SYSTEM ""> 21 <!--Added Math Symbols: Negated Relations-->
22 <!ENTITY % SYSTEM ""> 23 <!--Added Math Symbols: Ordinary-->
24 <!ENTITY % SYSTEM "">
25 <!--Added Math Symbols: Relations-->
26 <!ENTITY % SYSTEM ""> 27 <!--General Technical-->
28 <!ENTITY % SYSTEM "">
29 <!--Numbers and Currency symbols-->
30 <!ENTITY % SYSTEM "">
31 <!--MathML Aliases (From ISO PUB,DIA,NUM)-->
32 <!ENTITY % SYSTEM "">
33 <!--Greek Symbols-->
34 <!ENTITY % SYSTEM ""> 35 <!--Math Script Font-->
36 <!ENTITY % SYSTEM ""> 37 <!--Math Open Face Font-->
38 <!ENTITY % SYSTEM "">
39 <!--MathML Entities-->
40 <!ENTITY % SYSTEM "">
41 <!--Main MathML DTD -->
42 <!ENTITY % SYSTEM "">
43
44 ;
45 ;
46 ;
47 ;
48 ;
49 ;
50 ;
51 ; 52 ;
53 ;
54 ;
55 ;
56 ;
57 ;
C’est l’utilisateur qui définit s’il veut baliser les parties mathématiques de son document dans l’un ou l’autre de ces deux formalismes en chargeant, au moment de la compilation, la première ou la deuxième DTD.
Regardonsmaintenantcomment nouspouvonsutiliserles DTD introduitesci-dessus. Nous présentons un exemple de document multilingue LATEX (basé en partie sur les exemples de la section 9.2 du The LATEX companion[13]) .
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE document SYSTEM ""[
3 <!ENTITY LaTeX "\LaTeX{}">
4 <!ENTITY TeX "\TeX{}">
5 <!ENTITY dots "\dots">
6 <!ENTITY endash "--">
7 <!ENTITY emdash "---">
8 <!ENTITY nbsp "~">
9 <!ENTITY % "|footnote"> 10 <!ELEMENT footnote (#PCDATA|par)*>
11 ]>
12 <document class="article" xml:lang="en">
13 <frontmatter>
14 <title>The &LaTeX; DTD and multiple languages</title>
15 <author><name>Michel Goossens</name>
16 <thanks>Partly from an example in <emph>The &LaTeX; Companion</emph>
17 </thanks></author>
18 <date>August 4th, 1998</date>
19 </frontmatter>
20 <bodymatter>
21 <section id="sec-en">
22 <stitle>The basic principles</stitle>
23 <par>
24 This is an example input file. We start in English to show the
25 principle. You should especially pay attention that we have used
26 slightly different notation for some of the common &LaTeX; constructs,
27 such as the dashes, which come in three sizes: an intra-word dash, a
28 medium dash for number ranges like 1&endash;2, and a punctuation
29 dash&emdash;like this. Text can be emphasized as <emph>shown
30 here</emph>. An ellipsis is made with &dots; Footnotes<footnote>This
31 is a simple footnote.<par>It can also contain <texttt>par</texttt> 32 elements.</par></footnote> are tricky constructs, since one must be 33 careful not to nest them.
34 </par>
35 <subsection>
36 <stitle>Dealing with special characters</stitle>
37 <par>
38 XML has a different set of reserved characters than &LaTeX;, in
39 particular, when you want to use any of the three characters
40 <texttt><![CDATA[\&]]></texttt>, <texttt><![CDATA[<]]></texttt>,
41 and <texttt><![CDATA[>]]></texttt>, you should enter them as 42 <texttt>\&amp;</texttt>, <texttt>\&lt;</texttt>, and 43 <texttt>\&gt;</texttt>, respectively.
44 </par>
45 </subsection>
46 <subsection id="sec-math">
47 <stitle>&LaTeX; and mathematical formulae</stitle>
48 <par>
49 &LaTeX; and <emph>a fortiori</emph> &TeX; are very good at typesetting
50 mathematical formulae, like
51 <inlinemath><![CDATA[x- 3 y + z < 7]]></inlinemath> or 52 <inlinemath><![CDATA[a_{1} > x^{2n} + y^{2n} > x’]]></inlinemath> or 53 <inlinemath><![CDATA[(A, B) = \sum_{i} a_{i} b_{i}]]></inlinemath>.
54 Do not forget that for reasons of consistency, if you want to refer to
55 a variable in one of the formulae, such as the symbol
56 <inlinemath>x</inlinemath>, you must also use math mode in the text.
57 </par>
58 </subsection>
59 </section>
60 <section xml:lang="de">
61 <stitle>Beispiel eines Textes in deutscher Sprache</stitle>
62 <subsection>
63 <stitle>Eine EPS Abbildung</stitle>
64 <par>
65 Dieser Abschnitt zeigt, wie man eine PostScript-Abbildung 66 <cite refid="bib-PS"/> in ein Dokument einbinden kann.
67 Abbildung <ref refid="fig-psfig"/> wurde mit dem Befehl
68 <verbatim>
69 <![CDATA[\includegraphics[width="3cm"]{file="}]]>
70 </verbatim> 71 in den Text aufgenommen.
72 </par>
73 <figure id="fig-psfig">
74 <includegraphics width="3cm" file="colorcir"/>
75 <caption xml:lang="de">Ein EPS Bild</caption>
76 </figure>
77 </subsection>
78 <subsection>
79 <stitle>Beispiel einer Tabelle</stitle>
80 <par>Die Tabelle <ref refid="tab-exag"/> auf Seite <pageref 81 refid="tab-exag"/> zeigt eine Tabelle.
82 </par>
83 <table id="tab-exag">
84 <caption xml:lang="de">
85 Eingabe der deutschen Zusatzzeichen in &LaTeX;</caption>
86 <tabular preamble="ccccccc">
87 <row>
88 <cell><texttt>"a</texttt> ä</cell>
89 <cell><texttt>"A</texttt> Ä</cell>
90 <cell><texttt>"o</texttt> ö</cell>
91 <cell><texttt>"O</texttt> Ö</cell>
92 <cell><texttt>"u</texttt> ü</cell>
93 <cell><texttt>"U</texttt> Ü</cell>
94 <cell><texttt>"s</texttt> ß</cell>
95 </row>
96 </tabular>
97 </table>
98 </subsection>
99 </section>
100 <section xml:lang="fr">
101 <stitle>Continuation du texte en français</stitle>
102 <subsection id="sec-list">
103 <stitle>Traiter les listes</stitle>
104 <par>
105 Les listes sont utilisées fréquemment pour structurer ou mettre
106 en évidence certains éléments d’un document (voir <cite refid="bib-Liste"/>).
107 </par>
108 <itemize>
109 <item>Ceci est le premier élément d’une liste non-ordonnée. Chaque élément 110 de ce type de liste est précédé d’un signe distinctif, comme une 111 puce, un tiret, etc.
112 </item>
113 <item>Ce second élément de la même liste contient une liste de 114 <emph>description</emph> imbriquée.
115 <description>
116 <term>XML</term>
117 <item>Meta langage pour définir des classes de documents</item>
118 <term>XLL</term>
119 <item>Langage pour définir des hyperliens entre différentes
120 parties de documents XML</item>
121 </description>
122 Nous continuons notre texte à l’intérieur de la première liste.
123 </item>
124 </itemize>
125 </subsection>
126 </section>
127 <bibliography>
128 <bibitem id="bib-PS" xml:lang="de">
129 Adobe Inc. <emph>PostScript Handbuch (2. Auflage)</emph>
130 Addison-Wesley (Deutschland) GmbH, Bonn, 1991.
131 </bibitem>
132 <bibitem id="bib-Liste" xml:lang="fr">
133 Michel Goossens. Personnaliser les listes &LaTeX;.
134 <emph>Cahiers GUTenberg</emph>, 17:32&endash;48, mai 1994.
135 </bibitem>
136 </bibliography>
137 </bodymatter>
138 </document>
Dans ce fichier source, nous remarquons en particulier qu’implicitement nous utilisons la notation TEX pour les mathématiques (rappelons que c’est le choix par défaut dela ligne164dans la DTD ).Pour lesmathématiques, nous incluons des commandes TEX directement à l’intérieur de sections CDATA (lignes 51–53). Les caractères spéciaux de XML sont aussi saisis à l’aide de sections CDATA(lignes 40–41), tout commelecontenu duverbatimen général, lorsqu’onveut incluredu matériel non-XML dans un fichier XML —par exemple des sources en langues de programmation C, C++, Java, etc., qui utilisent les caractères spéciaux de XML, comme &, <—, il est toujours préférable de le mettre à l’intérieur d’une section CDATA.
Les différenteslangues sont déclarées à l’aidede l’attributxml:langsur les éléments document (ligne 12 pour l’anglais) et section (ligne 60 pour l’allemand et 100 pour le français), ainsi que sur bibitem (lignes 128, 132). Pour valider un document XML, cet attribut doit être déclaré pour tout élément auquel il peut être appliqué.
Voici une feuille de style XSL minilatex.xslqui traduit ce fichier en LATEX:
1 <?xml version=’1.0’?>
2 <!-- -->
3 <xsl:stylesheet version="1.0"
4 xmlns:xsl="; 5 xmlns=";>
6
7 <xsl:output method="text" indent="no" encoding="ISO-8859-1"/>
8
9 <xsl:strip-space elements="*"/>
10
11 <xsl:template name="label">
12 <xsl:apply-templates/>
13 <xsl:if test="../@id"><xsl:text>\label{</xsl:text>
14 <xsl:value-of select="../@id"/><xsl:text>}</xsl:text></xsl:if>
15 <xsl:text>}
16 </xsl:text>
17 </xsl:template>
18
19 <xsl:template match="document">
20 <xsl:text>\documentclass[]{</xsl:text>
21 <xsl:value-of select="@class"/>
22 <xsl:text>}
23 \usepackage[dvips]{graphicx}
24 \usepackage[T1]{fontenc}
25 \begin{document}
26 </xsl:text>
27 <xsl:apply-templates/>
28 <xsl:text>\end{document}
29 </xsl:text>
30 </xsl:template>
31
32 <!-- ================ Frontmatter element ======================= -->
33 <xsl:template match="frontmatter">
34 <xsl:apply-templates/>
35 <xsl:text>
36 \maketitle
37 </xsl:text>
38 </xsl:template>
39 <xsl:template match="frontmatter/title">
40 <xsl:text>
41 \title{</xsl:text>
42 <xsl:apply-templates/>
43 <xsl:text>}</xsl:text>
44 </xsl:template>
45 <xsl:template match="frontmatter/author">
46 <xsl:text>
47 \author{</xsl:text>
48 <xsl:apply-templates/>
49 <xsl:text>}
50 </xsl:text>
51 </xsl:template>
52 <xsl:template match="frontmatter/author/name">
53 <xsl:apply-templates/>
54 </xsl:template>
55 <xsl:template match="frontmatter/author/thanks">
56 <xsl:text>
57 \thanks{</xsl:text>
58 <xsl:apply-templates/>
59 <xsl:text>}</xsl:text>
60 </xsl:template>
61 <xsl:template match="frontmatter/author/inst">
62 <xsl:text>
63 \thanks{</xsl:text>
64 <xsl:apply-templates/>
65 <xsl:text>}</xsl:text>
66 </xsl:template>
67 <xsl:template match="frontmatter/date">
68 <xsl:text>
69 \date{</xsl:text>
70 <xsl:apply-templates/>
71 <xsl:text>}
72 </xsl:text>
73 </xsl:template>
74 <xsl:template match="frontmatter/abstract">
75 <xsl:text>
76 \begin{abstract}
77 </xsl:text>
78 <xsl:apply-templates/>
79 <xsl:text>
80 \end{abstract}
81 </xsl:text>
82 </xsl:template>
83 <xsl:template match="frontmatter/keywords">
84 <xsl:text>\keywords{</xsl:text>
85 <xsl:apply-templates/>
86 <xsl:text>}</xsl:text>
87 </xsl:template>
88
89 <!-- ===================== Bodymatter element =================== -->
90 <xsl:template match="bodymatter|part|chapter|section|subsection|
91 subsubsection|paragraph|subparagraph">
92 <xsl:apply-templates/>
93 </xsl:template>
94 <!-- =================== Section headings ======================= -->
95 <xsl:template match="part/stitle">
96 <xsl:text>\part{</xsl:text><xsl:call-template name="label"/>
97 </xsl:template>
98 <xsl:template match="chapter/stitle">
99 <xsl:text>\chapter{</xsl:text><xsl:call-template name="label"/>
100 </xsl:template>
101 <xsl:template match="section/stitle">
102 <xsl:text>\section{</xsl:text><xsl:call-template name="label"/>
103 </xsl:template>
104 <xsl:template match="subsection/stitle">
105 <xsl:text>\subsection{</xsl:text><xsl:call-template name="label"/>
106 </xsl:template>
107 <xsl:template match="subsubsection/stitle">
108 <xsl:text>\subsubsection{</xsl:text><xsl:call-template name="label"/>
109 </xsl:template>
110 <xsl:template match="paragraph/stitle">
111 <xsl:text>\paragraph{</xsl:text><xsl:call-template name="label"/>
112 </xsl:template>
113 <xsl:template match="subparagraph/stitle">
114 <xsl:text>\subparagraph{</xsl:text><xsl:call-template name="label"/>
115 </xsl:template>
116 <!-- ===================== Font changes ========================= -->
117 <xsl:template match="emph"> 118 <xsl:text>\emph{</xsl:text>
119 <xsl:apply-templates/>
120 <xsl:text>}</xsl:text>
121 </xsl:template>
122 <xsl:template match="textbf"> 123 <xsl:text>\textbf{</xsl:text>
124 <xsl:apply-templates/>
125 <xsl:text>}</xsl:text>
126 </xsl:template>
127 <xsl:template match="textsc"> 128 <xsl:text>\textsc{</xsl:text>
129 <xsl:apply-templates/>
130 <xsl:text>}</xsl:text>
131 </xsl:template>
132 <xsl:template match="textsf"> 133 <xsl:text>\textsf{</xsl:text>
134 <xsl:apply-templates/>
135 <xsl:text>}</xsl:text>
136 </xsl:template>
137 <xsl:template match="textsl"> 138 <xsl:text>\textsl{</xsl:text>
139 <xsl:apply-templates/>
140 <xsl:text>}</xsl:text>
141 </xsl:template>
142 <xsl:template match="texttt"> 143 <xsl:text>\texttt{</xsl:text>
144 <xsl:apply-templates/>
145 <xsl:text>}</xsl:text>
146 </xsl:template>
147 <!-- =================== Cross-references ======================= -->
148 <xsl:template match="cite">
149 <xsl:text>\cite{</xsl:text>
150 <xsl:value-of select="@refid"/>
151 <xsl:text>}</xsl:text>
152 </xsl:template>
153 <xsl:template match="pageref">
154 <xsl:text>\pageref{</xsl:text>
155 <xsl:value-of select="@refid"/>
156 <xsl:text>}</xsl:text>
157 </xsl:template>
158 <xsl:template match="ref">
159 <xsl:text>\ref{</xsl:text>
160 <xsl:value-of select="@refid"/>
161 <xsl:text>}</xsl:text>
162 </xsl:template>
163 <!-- =============== quotes, footnotes, verbatim ================ --> 164 <xsl:template match="footnote"> 165 <xsl:text>\footnote{</xsl:text>
166 <xsl:apply-templates/>
167 <xsl:text>}</xsl:text>
168 </xsl:template>
169 <xsl:template match="quote">
170 <xsl:text>
171 \begin{quote}</xsl:text> 172 <xsl:apply-templates/>
173 <xsl:text>\end{quote}</xsl:text> 174 </xsl:template>
175 <xsl:template match="quotation">
176 <xsl:text>
177 \begin{quotation}</xsl:text>
178 <xsl:apply-templates/>
179 <xsl:text>\end{quotation}</xsl:text>
180 </xsl:template>
181 <xsl:template match="verbatim">
182 <xsl:text>
183 \begin{verbatim}</xsl:text>
184 <xsl:apply-templates/>
185 <xsl:text>\end{verbatim}</xsl:text>
186 </xsl:template>
187 <!-- ========================= Lists ============================ -->
188 <xsl:template match="description">
189 <xsl:text>
190 \begin{description}
191 </xsl:text>
192 <xsl:apply-templates/>
193 <xsl:text>
194 \end{description}
195 </xsl:text>
196 </xsl:template>
197 <xsl:template match="description/term">
198 <xsl:text>
199 \item[</xsl:text>
200 <xsl:apply-templates/>
201 <xsl:text>]</xsl:text>
202 </xsl:template>
203 <xsl:template match="description/item">
204 <xsl:apply-templates/>
205 </xsl:template>
206 <xsl:template match="enumerate">
207 <xsl:text>
208 \begin{enumerate}
209 </xsl:text>
210 <xsl:apply-templates/>
211 <xsl:text>\end{enumerate}
212 </xsl:text>
213 </xsl:template>
214 <xsl:template match="itemize">
215 <xsl:text>
216 \begin{itemize}
217 </xsl:text>
218 <xsl:apply-templates/>
219 <xsl:text>\end{itemize}
220 </xsl:text>
221 </xsl:template>
222 <xsl:template match="enumerate|itemize/item">
223 <xsl:text>
224 \item </xsl:text>
225 <xsl:apply-templates/>
226 </xsl:template>
227 <xsl:template match="bibliography">
228 <xsl:text>
229 \begin{thebibliography}{99}
230 </xsl:text>
231 <xsl:apply-templates/>
232 <xsl:text>
233 \end{thebibliography}
234 </xsl:text>
235 </xsl:template>
236 <xsl:template match="bibliography/bibitem">
237 <xsl:text>\bibitem{</xsl:text>
238 <xsl:value-of select="@id"/>
239 <xsl:text>}</xsl:text>
240 <xsl:apply-templates/>
241 </xsl:template>
242 <!-- ====================== Mathematics ========================= -->
243 <xsl:template match="inlinemath">
244 <xsl:text>$</xsl:text>
245 <xsl:apply-templates/>
246 <xsl:text>$</xsl:text>
247 </xsl:template>
248 <xsl:template match="displaymath">
249 <xsl:text>
250 \begin{displaymath}
251 </xsl:text>
252 <xsl:apply-templates/>
253 <xsl:text>
254 \end{displaymath}
255 </xsl:text>
256 </xsl:template>
257 <xsl:template match="equation">
258 <xsl:text>
259 \begin{equation}
260 </xsl:text>
261 <xsl:apply-templates/>
262 <xsl:text>
263 \end{equation}
264 </xsl:text>
265 </xsl:template>
266 <xsl:template match="eqnarray">
267 <xsl:text>
268 \begin{eqnarray}
269 </xsl:text>
270 <xsl:apply-templates/>
271 <xsl:text>
272 \end{eqnarray}
273 </xsl:text>
274 </xsl:template>
275 <!-- ====================== A paragraph ========================= -->
276 <xsl:template match="par">
277 <xsl:text>
278 \par
279 </xsl:text>
280 <xsl:apply-templates/>
281 </xsl:template>
282 <!-- ======================== Tabular =========================== -->
283 <xsl:template match="tabular">
284 <xsl:text>
285 \begin{tabular}{</xsl:text>
286 <xsl:value-of select="@preamble"/><xsl:text>}
287 </xsl:text>
288 <xsl:apply-templates/>
289 <xsl:text>
290 \end{tabular}
291 </xsl:text>
292 </xsl:template>
293 <xsl:template match="tabular/row">
294 <xsl:apply-templates/>
295 <xsl:text>\\
296 </xsl:text>
297 </xsl:template>
298 <xsl:template match="tabular/row/cell">
299 <xsl:apply-templates/><xsl:text>&</xsl:text>
300 </xsl:template>
301 <xsl:template match="tabular/row/cell[position()=last()]" priority="2">
302 <xsl:apply-templates/>
303 </xsl:template>
304 <!-- ================== "floats" and their contents ============= -->
305 <xsl:template match="figure">
306 <xsl:text>
307 \begin{figure}\centering 308 </xsl:text>
309 <xsl:apply-templates/>
310 <xsl:text>\end{figure}
311 </xsl:text>
312 </xsl:template>
313 <xsl:template match="table">
314 <xsl:text>
315 \begin{table}\centering
316 </xsl:text>
317 <xsl:apply-templates/>
318 <xsl:text>\end{table}
319 </xsl:text>
320 </xsl:template>
321 <xsl:template match="figure/caption | table/caption">
322 <xsl:text>\caption{</xsl:text><xsl:call-template name="label"/>
323 </xsl:template>
324 <!-- ==================== Includegraphics ======================= -->
325 <xsl:template match="includegraphics">
326 <xsl:text>
327 \includegraphics[</xsl:text>
328 <xsl:if test="@width"><xsl:text>width=</xsl:text>
329 <xsl:value-of select="@width"/><xsl:text>, </xsl:text></xsl:if>
330 <xsl:if test="@height"><xsl:text>height=</xsl:text>
331 <xsl:value-of select="@height"/><xsl:text>, </xsl:text></xsl:if>
332 <xsl:if test="@bb"><xsl:text>bb="</xsl:text>
333 <xsl:value-of select="@bb"/><xsl:text>, </xsl:text></xsl:if>
334 <xsl:if test="@angle"><xsl:text>angle=</xsl:text>
335 <xsl:value-of select="@angle"/><xsl:text>, </xsl:text></xsl:if>
336 <xsl:if test="@scale"><xsl:text>scale=</xsl:text>
337 <xsl:value-of select="@scale"/><xsl:text></xsl:text></xsl:if>
338 <xsl:text>]{</xsl:text><xsl:value-of select="@file"/><xsl:text>}
339 </xsl:text>
340 </xsl:template>
341
342 </xsl:stylesheet>
Ce fichier de style a une structure assez linéaire et il ne devrait pas y avoir de difficultés particulières à comprendre comment les différents éléments sont traduits en LATEX. Nous mentionnons seulement la façon dont nous traitons les débuts de chapitres ou de sections (lignes 95–115) où nous avons paramétré la génération du titre et d’une commande LATEX \label à l’aide du modèle nommé label, défini en lignes
The LATEX DTD and multiple languages Michel Goossens ? August 4th, 1998 1 The basic principles This is an example input file. We start in English to show the principle. You should especially pay attention that we have used slightly different notation for some of the common LATEX constructs, such as the dashes, which come in three sizes: an intra-word dash, a medium dash for number ranges like 1–2, and a punctuation dash—like this. Text can be emphasized as shown here. An ellipsis is made with Footnotes1 are tricky constructs, since one must be careful not to nest them. 1.1 Dealing with special characters XML has a different set of reserved characters than LATEX, in particular, when you want to use any of the three characters , , and , you should enter them as , , and , respectively. 1.2 LATEX and mathematical formulae E X are very good at typesetting mathematical formulae, like x ? 3. Do not forget that for reasons of consistency, if you want to refer to a variable in one of the formulae, such as the symbol x, you must also use math mode in the text. 2 Beispiel eines Textes in deutscher Sprache 2.1 Eine EPS Abbildung Dieser Abschnitt zeigt, wie man eine PostScript-Abbildung [1] in ein Dokument einbinden kann. Abbildung 1 wurde mit dem Befehl ?Partly from an example in The LATEX Companion1This is a simple footnote. It can also contain elements. 1 | Figure 1: Ein EPS Bild Table 1: Eingabe der deutschen Zusatzzeichen in LATEX ä Ä ö Ö ü Ü SS in den Text aufgenommen. 2.2 Beispiel einer Tabelle Die Tabelle 1 auf Seite 2 zeigt eine Tabelle. 3 Continuation du texte en français 3.1 Traiter les listes Les listes sont utilisées fréquemment pour structurer ou mettre en évidence certains éléments d’un document (voir [2]). • Ceci est le premier élément d’une liste non-ordonnée. Chaque élément de ce type de liste est précédé d’un signe distinctif, comme une puce, un tiret, etc. • Ce second élément de la même liste contient une liste de description imbriquée. XML Meta langage pour définir des classes de documents XLL Langage pour définir des hyperliensentre différentes parties de documents XML Nous continuons notre texte à l’intérieur de la première liste. References [1] Adobe Inc. PostScript Handbuch (2. Auflage) Addison-Wesley (Deutschland) GmbH, Bonn, 1991. [2] Michel Goossens. Personnaliser les listes LATEX. Cahiers GUTenberg, 17:32–48, mai 1994. 2 |
FIGURE 14 – Un document XML balisé avec la DTD
.
11–17. Nous commençons par écrire le titre (élément stitle dans les motifs des lignes 95, 98, 101, etc.) avec l’instruction <xsl:apply-templates> de la ligne 12, puis nous vérifions si la section (le parent de stitle) a un attribut de type id (test ../@id en ligne 13), auquel cas nous introduisons une commande \label ayant comme clé la valeur de l’attribut en question (partie <xsl:value-of en ligne 14), puis nous fermons l’accolade contenant le titre de section (ligne 15) dont l’accolade ouverte se trouve en lignes 96, 99, 102, etc.
La figure 14 montre le résultat après traitement du fichier XML et la feuille de style XSL minilatex.xslavec un processeur XSL et avec LATEX.
B. Définition formelle des domaines nominaux
Cette annexe reprend les règles de production de la spécification des domaines nominaux. Le numéro de section dans la spécification[41] où les règles mentionnées sont introduites est indiqué dans le titre. La notation X renvoie à un numéro de production dans la spécification XML (voir page 191), N renvoie à un numéro de production pour les domaines nominaux.
B.1. Déclarer un domaine nominal (section 2)
[1] NSAttName ::= PrefixedAttNameN2 | DefaultAttNameN3
[2] PrefixedAttName ::= ’xmlns:’ NCNameN
[3] DefaultAttName ::= ’xmlns’
[4] NCName ::= (LetterX84 | ’_’) (NCNameCharN5)* [5] NCNameChar ::= LetterX84 | DigitX88 | ’.’ | ’-’ | ’_’ |
CombiningCharX87 | ExtenderX89
Les productions X4 et X5 de la spécification XML sont remplacées par N5 et N4, respectivement4.
B.2. Définir les noms qualifiés (section 3)
Le double point est utilisé pour séparer le préfixe ([7] Prefix) identifiant le domaine nominal de la partie « locale » ([8] LocalPart) du « nom qualifié » ([8] QNAME).
[6] QName ::= (PrefixN7 ’:’)? LocalPartN8
[7] Prefix ::= NCNameN4
[8] LocalPart ::= NCNameN4
B.3. Utiliser les noms qualifiés (section 4)
Avec l’introduction des domaines nominaux, plusieurs productions XML sont généralisées (à gauche le numéro de la production originale dans la spécificationde XML).
Règles de production pour les types d’élément
[9]X40 STag ::= ’<’ QNameN6 (SX3 AttributeN12)* SX3? ’>’
[10]X42 ETag ::= ’</’ QNameN6 SX3? ’>’
[11]X44 EmptyElemTag ::= ’<’ QNameN6 (SX3 AttributN12e)* SX3? ’/>’
Règles de production pour les attributs
[12]X41 Attribute ::= NSAttNameN1 EqX25 AttValueX10 |
QNameN6 EqX25 AttValueX10
Règles de production pour les déclarations
X28 X3 N6
[13] doctypedecl ::= ’<!DOCTYPE’ S QName (SX3 ExternalID?
(’[’ (markupdecl 29 | PEReference )* ’]’ SX3?)? ’>’
[14]X45 elementdecl ::= ’<!ELEMENT’ S 3 QName 6 S 3 contentspecX46
SX3? ’>’
X N X X
[15] 48 cp ::= (QName 6 | choice 49 | seq 50) (’?’|’*’|’+’)?
[16]X51 Mixed ::= ’(’ SX3? ’#PCDATA’ (SX3? ’|’ SX3? QNameN6)*
SX3? ’)*’ | ’(’ SX3? ’#PCDATA’ SX3? ’)’
AttlistDecl ::= ’<!ATTLIST’ SX3 QNameN6 AttDefN18* SX3? ’>’
AttDef ::= SX3 (QNameN6 | NSAttNameN1) SX3 AttTypeX54
SX3 DefaultDeclX60
C. Définition formelle de XPath
Pour permettre de reconstruirela grammaire deXPath, nous reproduisons dans cette section les différentes règles de production de ce langage et listons également les fonctions disponibles. La notation X renvoie à un numéro de production dans la spécification XML (voir page 191), N renvoie à un numéro de production dans la spécification pour les domaines nominaux (voir page 102) et P à un numéro de production dans Xpath.
C.1. Chemins de localisation (section 2)
Un chemin de localisation (location path)
– sélectionne un ensemble de nœuds dans l’arbre source;
– peut spécifier un chemin absolu commençant par / (relatif au nœud racine du document);
– peut spécifier un chemin relatif (ne commençant pas par /) au nœud contexte.
[1] | LocationPath ::= | RelativeLocationPath 3 | AbsoluteLocationPath 2 P |
[2] | AbsoluteLocationPath ::= | ’/’ RelativeLocationPath 3? P P | AbbreviatedAbsoluteLocationPath 10 |
[3] | RelativeLocationPath ::= | P Step 4 | RelativeLocationPath 3 ’/’ StepP4 P P | AbbreviatedRelativeLocationPath 11 |
Un chemin de localisation peut contenir plusieurs expressions récursivement sous forme d’une succession de chemins relatifs, collés ensemble avec le signe /.
P
Pas de localisation (section 2.1)
Les pas de localisation (location step) sont définit comme suit:
[4] | Step | ::= | AxisSpecifier 5 NodeTest 7 Predicate 8* P P | AbbreviatedStep 12 |
[5] | AxisSpecifier | ::= | AxisName 6 ’::’ P P | AbbreviatedAxisSpecifier 13 |
P P
Chaque pas (StepP4) dans la construction d’un chemin de localisation se compose:
– d’un identificateur d’axeT5 : choisir une direction relative; – d’un test sur le nœudT6 : que cherche-t-on?
– dezéroou plus deprédicatsT7 : listed’attributsà utiliser pour sélectionner le(s) nœud(s) en question.
Axes (section 2.2)
[6] | AxisName | ::= | ’ancestor’ | | ’ancestor-or-self’ |
| ’attribute’ | | ’child’ | |||
| ’descendant’ | | ’descendant-or-self’ | |||
| ’following’ | | ’following-sibling’ | |||
| ’namespace’ | | ’parent’ | |||
| ’preceding’ | ’self’ | | ’preceding-sibling’ |
Tests sur les nœuds (section 2.3)
[7] NodeTest ::= NameTestP37
| NodeTypeP38 ’(’ ’)’
| ’processing-instruction’ ’(’ LiteralP29 ’)’
Prédicats (section 2.4)
[8] Predicate ::= ’[’ PredicateExprP9 ’]’
[9] PredicateExpr ::= ExprP14
Syntaxe courte (section 2.5)
[10] AbbreviatedAbsoluteLocationPath ::= ’//’ RelativeLocationPathP3
[11] AbbreviatedRelativeLocationPath ::= RelativeLocationPathP3 ’//’ StepP4
[12] AbbreviatedStep | ::= ’.’ | ’..’ |
[13] AbbreviatedAxisSpecifier | ::= ’@’? |
C.2. Expressions
Expressions de base (section 3.1)
[14] Expr ::= OrExprP21
[15] PrimaryExpr ::= VariableReferenceP36
| ’(’ ExprP14 ’)’
| LiteralP29
| NumberP30
| FunctionCallP16Appels de fonctions (section 3.2)
P35
[16] FunctionCall ::= FuncionName
’(’ ( ArgumentP17 ( ’,’Argument )* )? ’)’
[17] Argument ::= ExprP14
Ensembles de nœuds (section 3.3)
[18] UnionExpr ::= PathExprP18
| UnionExprP17 ’|’ PathExprP18
[19] PathExpr ::= LocationPathP1
| FilterExprP19 | FilterExprP19 ’/’ RelativeLocationPathP3 | FilterExprP19 ’//’ RelativeLocationPathP3
[20] FilterExpr ::= PrimaryExprP14
| FilterExprP17 PredicateP7
Expressions booléennes (section 3.4)
[21] OrExpr | ::= AndExpr 22 | OrExpr 21 ’or’ AndExprP22 P |
[22] AndExpr | P ::= EqualityExpr 23 P | AndExpr 22 ’and’ EqualityExprP23 |
[23] EqualityExpr | P ::= RelationalExpr 24 P | EqualityExpr 23 ’=’ RelationalExprP24 P | EqualityExpr 23 ’!=’ RelationalExprP24 |
[24] RelationalExpr | P ::= AdditiveExpr 25 P | RelationalExpr 24 ’<’ AdditiveExprP25 P | RelationalExpr 24 ’>’ AdditiveExprP25 P | RelationalExpr 24 ’<=’ AdditiveExprP25 P | RelationalExpr 24 ’>=’ AdditiveExprP25 |
P
Expressions numériques (section 3.5)
P26
[25] AdditiveExpr ::= MultiplicativeExpr
| AdditiveExprP25 ’+’ MultiplicativeExprP2
| AdditiveExprP25 ’-’ MultiplicativeExprP26 [26] MultiplicativeExpr ::= UnaryExprP27
| MultiplicativeExprP26 MultiplyOperatorP34
UnaryExprP27
| MultiplicativeExprP26 ’div’ UnaryExprP27
| MultiplicativeExprP26 ’mod’ UnaryExprP27
[27] UnaryExpr ::= UnionExprP18
| ’-’ UnaryExprP27
Expressions de structure lexicale (section 3.7)
[28] ExprToken | ::= ’(’ | ’)’ | ’[’ | ’]’ | ’.’ | ’..’ | ’@’ | ’,’ | ’::’ | NameTest 37 | NodeTypeP38 P P | Operator 32 | FunctionNameP35 P | AxisName 6 | LiteralP29 P | Number 30 | VariableReferenceP36 |
[29] Literal | ::= ’"’ [^"]* ’"’ | "’" [^’]* "’" |
[30] Number | ::= Digits 31 (’.’ DigitsP31?)? P P | ’.’ Digits 31 |
[31] Digits | ::= [0-9]+ |
[32] Operator | ::= OperatorName 33 | MultiplyOperatorP34 P | ’/’ | ’//’ | ’|’ | ’+’ | ’-’ | ’=’ | ’!=’ | ’<’ | ’<=’ | ’>’ | ’>=’ |
[33] OperatorName | ::= ’and’ | ’or’ | ’mod’ | ’div’ |
[34] MultiplyOperator | ::= ’*’ |
[35] FunctionName | N ::= QName 6 - NodeTypeP38 |
[36] VariableReference ::= ’$’ NCNameN4
[37] NameTest ::= ’*’ | NCNameN4 ’:’ ’*’ | QNameN6
[38] NodeType ::= ’comment’ | ’node’
| ’processing-instruction’ | ’text’
[39] ExprWhitespace ::= SX3
D. Définition formelle de XSLT
La recommandation XSLT utilisele même modèle pour les données et les expressions que XPath, qui a été défini dans la section précédente. La notation P renvoie à un numéro de productionpour la recommandation XPath(voir page 104)et T à un numéro de production dans XSLT.
D.1. Motifs (XSLT section 5.2)
Les motifs de sélection de XSLT sont un sous-ensemble de ceux disponibles avec
XPath. Comme montré ci-dessous, seuls les axes child et attribute peuvent être
directement utilisés. | |
[1] Pattern | ::= LocationPathPattern 2 T | Pattern 1 ’|’ T LocationPathPattern 2 T |
[2] LocationPathPattern | ::= ’/’ RelativePathPattern 4? T | IdKeyPattern 3 ((’/’ | ’//’) T RelativePathPattern 4)? T | ’//’? RelativePathPattern 4 T |
[3] IdKeyPattern | ::= ’id’ ’(’ Literal 29 ’)’ P | ’key’ ’(’ Literal 29 ’,’ P P Literal 29 ’)’ |
[4] RelativePathPattern | ::= StepPattern 5 T | RelativePathPattern 4 ’/’ T StepPattern 5 T | RelativePathPattern 4 ’//’ T StepPattern 5 T |
[5] StepPattern | T ::= ChildOrAttributeAxisSpecifier 6 |
NodeTestP7 PredicateP8*
[6] ChildOrAttributeAxisSpecifier ::= AbbreviatedAxisSpecifierP13
| (’child’ | ’attribute’)
’::’
D.2. Éléments du vocabulaire XSLT par ordre alphabétique
Pour chaque élément nous donnons le titre et le numéro de la section où il est traité dans la recommandation XSLT, ainsi que sa syntaxe, indiquant l’endroit où l’élément peut être utilisé et ce qu’il peut contenir.
xsl:apply-imports Section 5.6 Overriding Template Rules.
<!-- catégorie : instruction -->
<xsl:apply-imports />
xsl:apply-templates Section 5.4 Applying Template Rules.
<!-- catégorie : instruction -->
<xsl:apply-templates select = node-set-expression mode = qname>
<!-- contient : (xsl:sort | xsl:with-param)* --> </xsl:apply-templates>
xsl:attribute Section 7.1.3 Creating Attributes with xsl:attribute.
<!-- catégorie : instruction -->
<xsl:attribute
name = { qname } namespace = { uri-reference }>
<!-- contient : template -->
</xsl:attribute>
xsl:attribute-set Section 7.1.4 Named Attribute Sets.
<!-- catégorie : élément de niveau supérieur -->
<xsl:attribute-set name = qname use-attribute-sets = qnames>
<!-- contient : xsl:attribute* -->
</xsl:attribute-set> xsl:call-template Section 6 Named Templates.
<!-- catégorie : instruction -->
<xsl:call-template name = qname>
<!-- contient : xsl:with-param* -->
</xsl:call-template> xsl:choose Section 9.2 Conditional Processing with xsl:choose.
<!-- catégorie : instruction -->
<xsl:choose>
<!-- contient : (xsl:when+, xsl:otherwise?) -->
</xsl:choose> xsl:comment Section 7.4 Creating Comments.
<!-- catégorie : instruction -->
<xsl:comment>
<!-- contient : template -->
</xsl:comment> xsl:copy Section 7.5 Copying.
<!-- catégorie : instruction -->
<xsl:copy use-attribute-sets = qnames>
<!-- contient : template -->
</xsl:copy>
xsl:copy-of Section 11.3 Using Values of Variables and Parameters with xsl:copy-of.
<!-- catégorie : instruction -->
<xsl:copy-of select = expression /> xsl:decimal-format Section 12.3 Number Formatting.
<!-- catégorie : élément de niveau supérieur -->
<xsl:decimal-format name = qname decimal-separator = char grouping-separator = char infinity = string minus-sign = char NaN = string percent = char per-mille = char zero-digit = char digit = char pattern-separator = char />
xsl:element Section 7.1.2 Creating Elements with xsl:element.
<!-- catégorie : instruction -->
<xsl:element
name = { qname } namespace = { uri-reference } use-attribute-sets = qnames>
<!-- contient : template -->
</xsl:element> xsl:fallback Section 15 Fallback.
<!-- catégorie : instruction -->
<xsl:fallback>
<!-- contient : template -->
</xsl:fallback> xsl:for-each Section 8. Repetition.
<!-- catégorie : instruction -->
<xsl:for-each select = node-set-expression>
<!-- contient : (xsl:sort*, template) -->
</xsl:for-each>
xsl:if | Section 9.1 Conditional Processing with xsl:if. <!-- catégorie : instruction --> <xsl:if test = boolean-expression> <!-- contient : template --> </xsl:if> |
xsl:import | Section 2.6.2 Stylesheet Import. |
<xsl:import href = uri-reference /> xsl:include Section 2.6.1 Stylesheet Inclusion.
<!-- catégorie : élément de niveau supérieur -->
<xsl:include href = uri-reference />
xsl:key Section 12.2 Keys.
<!-- catégorie : élément de niveau supérieur -->
<xsl:key name = qname match = pattern use = node-set-expression />
xsl:message Section 13 Messages.
<!-- catégorie : instruction -->
<xsl:message terminate = "yes" | "no">
<!-- contient : template -->
</xsl:message>
xsl:namespace-alias Section 7.1.1 Literal Result Elements.
<!-- catégorie : élément de niveau supérieur -->
<xsl:namespace-alias stylesheet-prefix = prefix | "#default" result-prefix = prefix | "#default" />
xsl:number Section 7.7 Numbering.
<!-- catégorie : instruction -->
<xsl:number level = "single" | "multiple" | "any" count = pattern from = pattern value = number-expression format = { string } lang = { nmtoken }
letter-value = { "alphabetic" | "traditional" } grouping-separator = { char } grouping-size = { number } />
xsl:otherwise Section 9.2 Conditional Processing with xsl:choose.
<xsl:otherwise>
<!-- contient : template -->
</xsl:otherwise> xsl:output Section 16 Output.
<!-- catégorie : élément de niveau supérieur --> <xsl:output
method = "xml" | "html" | "text" | qname-but-not-ncname version = nmtoken encoding = string omit-xml-declaration = "yes" | "no" standalone = "yes" | "no" doctype-public = string doctype-system = string cdata-section-elements = qnames indent = "yes" | "no" media-type = string />
xsl:param Section 11 Variables and Parameters.
<!-- catégorie : élément de niveau supérieur -->
<xsl:param name = qname select = expression>
<!-- contient : template -->
</xsl:param>
xsl:preserve-space Section 3.4 Whitespace Stripping.
<!-- catégorie : élément de niveau supérieur -->
<xsl:preserve-space elements = tokens />
xsl:processing-instruction Section 7.3 Creating Processing Instructions.
<!-- catégorie : instruction -->
<xsl:processing-instruction name = { ncname }> <!-- contient : template -->
</xsl:processing-instruction> xsl:sort Section 10 Sorting.
<xsl:sort select = string-expression lang = { nmtoken } data-type = { "text" | "number" } order = { "ascending" | "descending" } case-order = { "upper-first" | "lower-first" } />
xsl:strip-space Section 3.4 Whitespace Stripping.
<!-- catégorie : élément de niveau supérieur -->
<xsl:strip-space elements = tokens />
xsl:stylesheet Section 2.2 Stylesheet Element (comme xsl:transform).
<xsl:stylesheet id = id
extension-element-prefixes = tokens exclude-result-prefixes = tokens version = number>
<!-- contient : (xsl:import*, élément de niveau supérieurs) -->
</xsl:stylesheet>
xsl:template Section 5.3 Defining Template Rules.
<!-- catégorie : élément de niveau supérieur -->
<xsl:template match = pattern name = qname priority = number mode = qname>
<!-- contient : (xsl:param*, template) -->
</xsl:template>
xsl:text Section 7.2 Creating Text.
<!-- catégorie : instruction -->
<xsl:text disable-output-escaping = "yes" | "no">
<!-- contient : #PCDATA -->
</xsl:text>
xsl:transform Section 2.2 Stylesheet Element (alias pour xsl:stylesheet).
<xsl:transform id = id
extension-element-prefixes = tokens exclude-result-prefixes = tokens version = number>
<!-- contient : (xsl:import*, élément de niveau supérieurs) -->
</xsl:transform>
xsl:value-of Section 7.6.1 Generating Text with xsl:value-of.
<!-- catégorie : instruction -->
<xsl:value-of select = string-expression disable-output-escaping = "yes" | "no" />
xsl:variable Section 11 Variables and Parameters.
<!-- catégorie : élément de niveau supérieur -->
<!-- catégorie : instruction -->
<xsl:variable name = qname select = expression>
<!-- contient : template --> </xsl:variable>
xsl:when Section 9.2 Conditional Processing with xsl:choose.
<xsl:when test = boolean-expression> <!-- contient : template -->
</xsl:when>
xsl:with-param Section 11.6 Passing Parameters to Templates.
<xsl:with-param name = qname select = expression>
<!-- contient : template -->
</xsl:with-param>
E. Fonctions XPath et XSLT par ordre alphabétique
Pour chaque fonction, nous spécifions son type et la section où elle est traitée dans les recommandations XPath or XSLT.
boolean(object) booléenne (XPath, 4.3 Boolean Functions). ceiling(number) numérique (XPath, 4.4 Number Functions).
concat(string,string,string*) chaîne de caractères (XPath, 4.2 String Functions).
contains(string,string) chaîne de caractères (XPath, 4.2 String Functions). count(node-set) ensemble de nœuds (XPath, 4.1 Node Set Functions). current() ensemble de nœuds
(XSLT, 12.4 Miscellaneous Additional Functions).
document(object, node-set?) ensemble de nœuds
(XSLT, 12.1 Multiple Source Documents).
element-available(string) booléenne (XSLT, 15 Fallback). false() booléenne (XPath, 4.3 Boolean Functions). floor(number) numérique (XPath, 4.4 Number Functions). format-number(number,string,string?)chaîne de caractères (XSLT, 12.3 Number Formatting).
function-available(string) booléenne (XSLT, 15 Fallback).
generate-id(node-set?) ensemble de nœuds
(XSLT, 12.4 Miscellaneous Additional Functions).
id(object) ensemble de nœuds (XPath, 4.1 Node Set Functions).
key(string,object) ensemble de nœuds (XSLT, 12.2 Keys). lang(string) booléenne (XPath, 4.3 Boolean Functions). last() ensemble de nœuds (XPath, 4.1 Node Set Functions). local-name(node-set?) ensemble de nœuds (XPath, 4.1 Node Set Functions).
name(node-set?) ensemble de nœuds (XPath, 4.1 Node Set Functions).
namespace-uri(node-set?) ensemble de nœuds (XPath, 4.1 Node Set Functions).
normalize-space(string?) chaîne de caractères (XPath, 4.2 String Functions). not(boolean) booléenne (XPath, 4.3 Boolean Functions). number(object?) numérique (XPath, 4.4 Number Functions).
position() ensemble de nœuds (XPath, 4.1 Node Set Functions).
round(number) numérique (XPath, 4.4 Number Functions).
starts-with(string,string) chaîne de caractères (XPath, 4.2 String Functions).
string(object?) chaîne de caractères (XPath, 4.2 String Functions). string-length(string?) numérique (XPath, 4.2 String Functions).
substring(string,number,number?) chaîne de caractères (XPath, 4.2 String Functions).
substring-after(string,string) chaîne de caractères (XPath, 4.2 String Functions).
substring-before(string,string) chaîne de caractères (XPath, 4.2 String Functions).
sum(node-set) numérique (XPath, 4.4 Number Functions).
system-property(string) object système identifié comme un nom qualifié (XSLT, 12.4 Miscellaneous Additional Functions).
translate(string,string,string) chaîne de caractères (XPath, 4.2 String Functions).
true() booléenne (XPath, 4.3 Boolean Functions). unparsed-entity-uri(string) chaîne de caractères
(XSLT, 12.4 Miscellaneous Additional Functions).
F. Terminologie bilingue XML
Il n’est pas toujours facile de traduire des termes techniques des spécifications W3C. En particulier, pour les textes de XML, XSL, XLink et XPointer, nous avons quelquefois dûcréer unnéologisme.Heureusement, nous étionsaidéspar lefaitquela norme ISO SGML est une des rares à être traduite en français[38]. En plus les volontaires qui ont contribué à la traduction de la spécification XML (voir page 191)ont augmenté considérablement la liste. Le tableau qui suit contient des termes puisés dans ces deux listes ainsi que quelques nouvelles traductions de termes que nous avons utilisées dans le présent texte. Il est clair que ces dernières n’ont qu’une valeur subjective et que nous adopterons volontiers dans le futur une traduction « officielle » dès qu’elle existera.
TERME ANGLAIS | TRADUCTIONPROPOSÉE |
ampersand | esperluette |
attribute | attribut |
attribute-list declaration | déclaration de liste d’attributs |
attribute specification | spécification d’attribut, stipulation d’attribut |
attribute-value normalization | normalisation de valeur d’attribut |
base character | caractère de base |
big-endian | grand-boutien |
bypassed | outrepassé |
CDATA section | section CDATA |
character | caractère |
character data | données textuelles |
character encoding | codage des caractères |
character reference | appel de caractère |
child element | sous-élément |
choice list of content particles | liste d’options de particules (de contenu) |
combining character | caractère jonctif |
compatibility area | zone de compatibilité |
compatibility decomposition | décomposition de compatibilité |
compatibility formatting tag | balise de formatage de compatibilité |
conditional section | section conditionnelle |
consexte node | nœud contexte |
constraint | contrainte |
construct | construction, production |
content particle | particule de contenu, particule |
cookie | témoin de connexion, mouchard |
declaration | déclaration |
document | document |
document element | élément document |
document type declaration | déclaration de type de document |
document type definition | définition de type de document |
element | élément |
element content | contenu élémentaire |
element-content model | modèle de contenu élémentaire |
empty-element tag | balise d’élément vide |
end-tag | balise de fin, balise fermante |
entity | entité |
entity reference | appel d’entité |
enumerated type | type énuméré |
TERME ANGLAIS | TRADUCTIONPROPOSÉE | |||
escape (to) | masquer | |||
extender | modificateur de lettre | |||
external entity | entité externe | |||
follow set | ensemble des suivants | |||
generic identifier | identificateur générique | |||
internal entity | entité interne | |||
litteral entity value | valeur littérale d’entité | |||
little-endian | petit-boutien | |||
location path | chemin de localisation | |||
locator | localisateur, élément de localisation | |||
markup | balisage | |||
markup declaration | déclaration de balisage | |||
match | correspondre, correspondance | |||
match pattern | motif de correspondance | |||
mixed content | contenu mixte | |||
name | nom | |||
name characters | caractères constitutifs de nom | |||
name start characters | caractères initiaux de nom | |||
name token | unité lexicale nominale, atome nominal | |||
named template | modèle nommé | |||
non-terminal | non-terminal | |||
notation | notation | |||
notation type | type notation | |||
notify | signalé | |||
numeric character reference | appel de caractère numérique | |||
parameter entity | entité paramètre | |||
parsed data | données parsées, données analysables | |||
parsed entity | entité parsée, entité analysable | |||
parsed textual data | données textuelles parsées, données textuelles analysées | |||
pattern | motif | |||
processing instruction | instruction de traitement | |||
prolog | prologue | |||
proper nesting | imbrication stricte | |||
proxy | mandataire | |||
pull | recherche ou extraction individuelle | |||
push | distribution sélective | |||
replacement text | texte de remplacement | |||
root element | élément racine | |||
rule, production, construct | production, règle | |||
selection pattern | motif de sélection | |||
sequence list of content particles | liste de suite de particules [de contenu] | |||
standalone document | document autonome | |||
TERME ANGLAIS | TRADUCTIONPROPOSÉE | |||
standardization | standardisation | |||
start-tag | balise de début, balise ouvrante | |||
set of attributes | jeu d’attributs | |||
set of tokenized types | série de types atomiques | |||
string expressions | expressions contenant des chaînes de caractères | |||
string type | type chaîne [de caractères] | |||
surrogates | substituts | |||
system identifier | identificateur système | |||
text declaration | déclaration de texte | |||
token, tokenized, tokenizer | atome, atomisé, atomiseur | |||
tokenized type | type atomique | |||
trailing blanks | blancs de queue | |||
unparsed entity | entité non-parsée, entité non-analysable | |||
URL | adresse universelle | |||
valid, validity, validation | valide, validité, validation | |||
validating [XML]processor | processeur [XML] validateur | |||
well-formed | bien formé | |||
well-formedness constraint | contrainte de forme | |||
white space | séparateur, du blanc | |||
XML processor | processeur XML | |||
G. Traduire un fichier HTML en LATEX
Cette section présente une feuille de style XSL pour transformer un fichier HTML relativement simple en LATEX. Habituellement, il faut traiter le fichier d’abord avec l’utilitaire tidy[28] pour générer du XHTML (une version XML de HTML). Cette feuille de style traite uniquement les éléments de HTML qui ne sont pas trop orientés vers une présentation visuelle. Pour ceux-là, le plus souvent, il faut compléter ce qui suit par du code ad hoc pour traiter les structures plus complexes (tables, formes, effets coloriés, polices spéciales, etc.).
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE xsl:stylesheet [
3 <!ENTITY lt "<"> 4 <!ENTITY gt ">">
5 <!ENTITY amp "&">
6 <!ENTITY nbsp " ">
7 ]>
8 <xsl:stylesheet version="1.0" xmlns:xsl=";
9 xmlns=";>
10
11 <xsl:strip-space elements="a par"/>
12
13 <xsl:output method="text" indent="no" encoding="ISO-8859-1"/>
14
15 <xsl:template name="label">
16 <xsl:apply-templates/>
17 <xsl:text>}</xsl:text><!-- fermer } de la commande section{ -->
18 <xsl:if test="a[@name]">
19 <xsl:text>\label{</xsl:text>
20 <xsl:value-of select="a/@name"/>
21 <xsl:text>}
</xsl:text>
22 </xsl:if>
23 </xsl:template>
24
25 <!-- ========= Root node ============ -->
26 <xsl:template match="/">
27 <xsl:text>\documentclass{article}
28 \usepackage{fromhtml}
29 \usepackage[T1]{fontenc}
30 \begin{document}
31 </xsl:text>
32 <xsl:apply-templates/>
33 <xsl:text>\end{document}
</xsl:text>
34 </xsl:template>
35
36 <!-- ========= Section headings ============ -->
37 <xsl:template match="h1">
38 <xsl:text>
\section*{</xsl:text>
39 <xsl:call-template name="label"/>
40 </xsl:template>
41 <xsl:template match="h2">
42 <xsl:text>
\subsection*{</xsl:text>
43 <xsl:call-template name="label"/>
44 </xsl:template>
45 <xsl:template match="h3">
46 <xsl:text>
\subsubsection*{</xsl:text>
47 <xsl:call-template name="label"/>
48 </xsl:template>
49 <xsl:template match="h4">
50 <xsl:text>
\paragraph{</xsl:text>
51 <xsl:call-template name="label"/>
52 </xsl:template>
53 <xsl:template match="h5|h6">
54 <xsl:text>
\subparagraph{</xsl:text>
55 <xsl:call-template name="label"/>
56 </xsl:template>
57
58 <!-- ========= Emphasis ============ -->
59
60 <xsl:template match="font"><!-- just continue -->
61 <xsl:apply-templates/>
62 </xsl:template>
63 <xsl:template match="font/@color">
64 <xsl:text>{\bfseries\itshape </xsl:text>
65 <xsl:apply-templates/>
66 <xsl:text>}</xsl:text>
67 </xsl:template>
68 <xsl:template match="font"><!-- just continue -->
69 <xsl:apply-templates/>
70 </xsl:template>
71 <xsl:template match="cite|em|i|var">
72 <xsl:text>\emph{</xsl:text>
73 <xsl:apply-templates/>
74 <xsl:text>}</xsl:text>
75 </xsl:template>
76 <xsl:template match="b|strong">
77 <xsl:text>\textbf{</xsl:text>
78 <xsl:apply-templates/>
79 <xsl:text>}</xsl:text>
80 </xsl:template>
81 <xsl:template match="tt|code">
82 <xsl:text>\texttt{</xsl:text>
83 <xsl:apply-templates/>
84 <xsl:text>}</xsl:text>
85 </xsl:template>
86 <xsl:template match="big">
87 <xsl:text>{\large </xsl:text>
88 <xsl:apply-templates/>
89 <xsl:text>}</xsl:text>
90 </xsl:template>
91 <xsl:template match="small">
92 <xsl:text>{\small </xsl:text>
93 <xsl:apply-templates/>
94 <xsl:text>}</xsl:text>
95 </xsl:template>
96 <xsl:template match="center">
97 <xsl:text>
\begin{center}
</xsl:text>
98 <xsl:apply-templates/>
99 <xsl:text>
\end{center}</xsl:text>
100 </xsl:template>
101 <!-- ======== Cross-references ======== -->
102 <xsl:template match="ref">
103 <xsl:text>\ref{</xsl:text>
104 <xsl:value-of select="@refid"/>
105 <xsl:text>}</xsl:text>
106 </xsl:template>
107 <!-- ====== quotes, footnotes, verbatim ====== -->
108 <xsl:template match="blockquote">
109 <xsl:text>
\begin{quote}</xsl:text>
110 <xsl:apply-templates/>
111 <xsl:text>\end{quote}
</xsl:text>
112 </xsl:template>
113 <xsl:template match="pre">
114 <xsl:text>
\begin{verbatim}</xsl:text>
115 <xsl:apply-templates/>
116 <xsl:text>\end{verbatim}
</xsl:text> 117 </xsl:template>
118 <!-- ============ Lists ============== -->
119 <xsl:template match="dl">
120 <xsl:text>
\begin{description}
</xsl:text>
121 <xsl:apply-templates/>
122 <xsl:text>
\end{description}
</xsl:text>
123 </xsl:template>
124 <xsl:template match="dl/dt">
125 <xsl:text>
\item[</xsl:text>
126 <xsl:apply-templates/>
127 <xsl:text>]</xsl:text>
128 </xsl:template>
129 <xsl:template match="dl/dd">
130 <xsl:apply-templates/>
131 <xsl:if test="name(following::*[1]) = ’dd’">
132 <xsl:text>
\par
</xsl:text>
133 </xsl:if>
134 </xsl:template>
135 <xsl:template match="ol">
136 <xsl:text>
\begin{enumerate}
</xsl:text>
137 <xsl:apply-templates/>
138 <xsl:text>
\end{enumerate}
</xsl:text>
139 </xsl:template>
140 <xsl:template match="ul">
141 <xsl:text>
\begin{itemize}
</xsl:text>
142 <xsl:apply-templates/>
143 <xsl:text>
\end{itemize}
</xsl:text>
144 </xsl:template>
145 <xsl:template match="ol/li">
146 <xsl:text>
\item </xsl:text>
147 <xsl:apply-templates/>
148 </xsl:template>
149 <xsl:template match="ul/li">
150 <xsl:text>
\item </xsl:text>
151 <xsl:apply-templates/>
152 </xsl:template>
153 <!-- ===== sub, sup -->
154 <xsl:template match="sub">
155 <xsl:text>\(\sb{</xsl:text>
156 <xsl:apply-templates/>
157 <xsl:text>}\)</xsl:text> 158 </xsl:template>
159 <xsl:template match="sup">
160 <xsl:text>\(\sp{</xsl:text>
161 <xsl:apply-templates/>
162 <xsl:text>}\)</xsl:text>
163 </xsl:template>
164 <!-- ===== a, br, code, hr, paragraph and url -->
165 <xsl:template match="a[@name]">
166 <!-- traité par les headings <hi> -->
167 <xsl:apply-templates/>
168 </xsl:template>
169 <xsl:template match="a[@href]">
170 <xsl:apply-templates/>
171 <xsl:choose>
172 <xsl:when test="substring(@href,1,1)=’#’">
173 <xsl:text> (page \pageref{</xsl:text>
174 <xsl:value-of select="@href"/>
175 <xsl:text>})</xsl:text>
176 </xsl:when>
177 <xsl:otherwise>
178 <xsl:text> (\url{</xsl:text>
179 <xsl:value-of select="@href"/>
180 <xsl:text>})</xsl:text>
181 </xsl:otherwise>
182 </xsl:choose>
183 </xsl:template>
184 <xsl:template match="br">
185 <xsl:text>\newline </xsl:text>
186 </xsl:template>
187 <xsl:template match="code|kbd|samp">
188 <xsl:text>{\ttfamily </xsl:text>
189 <xsl:apply-templates/>
190 <xsl:text>}</xsl:text>
191 </xsl:template>
192 <xsl:template match="hr">
193 <!-- ne rien faire --> 194 </xsl:template>
195 <xsl:template match="p">
196 <xsl:text>

</xsl:text> <!-- ligne blanche -->
197 <xsl:apply-templates/>
198 </xsl:template>
199 <!-- ===== tabular ===== --> 200 <xsl:template match="table">
201 <xsl:text>\begin{tabulary}{\textwidth}{</xsl:text>
202 <xsl:for-each select="tr[1]/td">
203 <xsl:choose>
204 <xsl:when test="@align=’right’">
205 <xsl:text>R</xsl:text>
206 </xsl:when>
207 <xsl:when test="@align=’center’">
208 <xsl:text>C</xsl:text>
209 </xsl:when>
210 <xsl:otherwise>
211 <xsl:text>L</xsl:text>
212 </xsl:otherwise>
213 </xsl:choose> 214 </xsl:for-each>
215 <xsl:text>L}</xsl:text>
216 <xsl:apply-templates/>
217 <xsl:text>\end{tabulary}</xsl:text>
218 </xsl:template>
219
220 <xsl:template match="tr|th">
221 <xsl:apply-templates/>
222 <xsl:text>\\\empty
</xsl:text>
223 </xsl:template>
224
225 <xsl:template match="tr/td|tr/th">
226 <xsl:apply-templates/>
227 <xsl:text>\TaB </xsl:text>
228 </xsl:template>
229
230 <xsl:template match="tr/td[position()=last()]" priority="2">
231 <xsl:apply-templates/>
232 </xsl:template>
233
234 <xsl:template match="tr/th[position()=last()]" priority="2">
235 <xsl:apply-templates/>
236 </xsl:template>
237 <!-- ======= "floats" and their contents ========= -->
238 <xsl:template match="img">
239 <xsl:text>
\includegraphics{</xsl:text>
240 <xsl:value-of select="@src"/>
241 <xsl:text>}
</xsl:text>
242 </xsl:template>
243
244 <!-- région attrape tout -->
245
246 <xsl:template match="form|head">
247 <!-- éliminer les forms et le head --> 248 </xsl:template>
249
250 <xsl:template match="html|body|span">
251 <xsl:apply-templates/><!-- continuer -->
252 </xsl:template>
253
254 <xsl:template match="text()">
255 <xsl:value-of select="translate(.,’ ?’,’ ’)"/>
256 </xsl:template>
257
258 <xsl:template match="*">
259 <xsl:text>
\par ******* Élément non reconnu ******* </xsl:text>
260 <xsl:value-of select="name(.)"/>
261 <xsl:text> ****
</xsl:text>
262 <xsl:apply-templates/>
263 \end{flushleft}
264 </xsl:template>
265 </xsl:stylesheet>
Remerciements
Je tiens à remercier Sebastian RAHTZ pour une collaboration fructueuse, des discussionsstimulanteset pour l’aidetechnique avec quelques figuresrécalcitrantes.David CARLISLE était toujours prêt à répondre à mes questions XSL, même les plus stupides.
Plusieurs personnes ont eu la gentillesse de relire une version préliminaire de cet article: Lisiane BESSON, Bernard GAULLE, Michèle JOUHET, Maurice LAUGIER.
Par ses commentaires enrichissants et ses suggestions constructives Jacques ANDRÉ a considérablement contribué à améliorer le texte du présent article.
Évidemment j’assume,comme auteur, la responsabilitéde toutes les fautes et imprécisions restantes.
Bibliographie
[1] Alis Technologies inc. Liste des noms des caractères ISO 10646-1 (1993).
[2] Jacques ANDRÉ et Michel GOOSSENS. « Codage des caractères et multi-linguisme: de l’Ascii à Unicode et ISO/IEC-10646.» Cahiers GUTenberg, no 20, pages 1–54, mai 1995.
[3] Ronald BOURRET. XML and Databases
[4] Lou BURNARD et C.M. SPERBERG-MCQUEEN.« La TEI simplifiée: une introduction au codage des textes électroniques en vue de leur échange. » Cahiers GUTenberg, no 24, pages 23–152, juin 1996.
[5] James CLARK. xt, an implementation in Java of XSL Transformations.
[6] James CLARK. nsgmls, an SGML System Conforming to ISO Standard 8879. [7] James CLARK. nsgmls, Output Format.
[8] Robin COVER (Oasis). The SGML/XML Web Page (XSL).
[9] Dale DOUGHERTY. The Making of the DocBook DTD. [10] Daniel GLAZMAN. CSS2 Feuilles de styles HTML. Éditions Eyrolles, Paris, 1999.
[11] Charles F. GOLDFARB. The SGML Handbook. Oxford University Press, 1992.
[12] Michel GOOSSENS. « Introduction pratique à SGML. » Cahiers GUTenberg, no 19, pages 27–58, janvier 1995.
[13] Michel GOOSSENS, Frank MITTELBACH et Alexander SAMARIN. The LATEX Companion. Addison-Wesley, Reading, 1995.
[14] Michel GOOSSENS, Sebastian RAHTZ et Frank MITTELBACH. The LATEX Graphics Companion. Addison-Wesley, Reading, 1997.
[15] Michel GOOSSENS et Sebastian RAHTZ. The LATEX Web Companion. Addison-Wesley, Reading, 1999.
[16] Eric van HERWIJNEN. SGML PRATIQUE. International Thomson Publishing France, Paris, 1995.
[17] Ken HOLMAN. Practical Transformation Using XSLT and XPath. [18] IBM alphaWorks. LotusXSL, an XSL processor in Java.
[19] IBM alphaWorks. A prototype Scalable Vector Graphics (SVG) viewer.
[20] IBM alphaWorks. xmlviewer, a Java class for viewing XML documents. [21] IBM alphaWorks. XML4J, XML parser for Java.
[22] The Internet Society. Tim BERNERS-LEE et al. Uniform Resource Identifiers (URI): Generic Syntax.
[23] Leslie Michel LAMPORT. LATEX User’s Guide and Reference Manual, Second Edition. Addison-Wesley, Reading, 1994.
[24] Alain MICHARD. XML Langage et applications. Éditions Eyrolles, Paris, 1999.
[25] Nic MILOSLAV. Introduction to XSL. [26] Mulberry Technologies. XSL-List — Open Forum on XSL. [27] Dave PAWSON. XSL Frequently Asked Questions.
[28] David RAGGETT. Clean up your Web pages with HTML Tidy. [29] Sebastian RAHTZ. Passive TEX.
[30] Sebastian RAHZT et Michel GOOSSENS. PassiveTeX: XML and TEX, doing it together
[31] Sebastian RAHTZ. TEI and XSL.
[32] Gaspar SINAI et Roman CZYBORRA. Yudit Unicode editor.
[33] C.M. SPERBERG-MCQUEEN et Lou BURNARD (rédacteurs).
Guidelines for Electronic Text Encoding and Interchange.
Chicago, Oxford: Text Encoding Initiative, 1994.
[34] James TAUBER. FOP: A Formatting Object to PDF Formatter/Renderer.
[35] THE UNICODE CONSORTIUM. The Unicode Standard, Version 2.0. Addison-Wesley, Reading, 1996.
[36] Norman WALSH (Oasis) The Docbook DTD and stylesheets.
[37] International Organization for Standardization. Hypermedia/Time-based Structuring Language (Hytime). ISO 10744, ISO Geneva, 1992.
[38] Organisation internationale de normalisation. Langage normalisé de balise généralisé (SGML). ISO 8879-1986(F), ISO Genève, 1986.
[39] World Wide Web Consortium, Håkon Wium LIE et Bert BOS (rédacteurs).
Cascading Style Sheets, level 1.
[40] World Wide Web Consortium, Håkon Wium LIE, Bert BOS, Chris LILLEY et Ian JACOBS (rédacteurs). Cascading Style Sheets, level 2.
[41] World Wide Web Consortium. Tim BRAY, Dave HOLLANDER et Andrew LAYMAN (rédacteurs). Namespaces in XML.
[42] World Wide Web Consortium. QL’98 - The Query Languages Workshop.
[43] World Wide Web Consortium. Jon FERRAIOLO (rédacteur). Scalable Vector Graphics (SVG) 1.0 Specification. Working Draft.
[44] World Wide Web Consortium. Murray ALTHEIM et Shane MCCARRON (rédacteurs). XHTML 1.1 - Module-based XHTML.
[45] World Wide Web Consortium. Murray ALTHEIM, Frank BOUMPHREY, Sam DOOLEY, Shane MCCARRON et Ted WUGOFSKI (rédacteurs). Modularization of XHTML.
[46] World Wide Web Consortium. Tim BRAY, Jean PAOLI et C. M. SPERBERG-MCQUEEN (rédacteurs). Extensible Markup Language (XML) 1.0.
[47] World Wide Web Consortium. Steve DEROSE, David ORCHARD et Ben TRAFFORD (rédacteurs). XML Linking Language (XLink). Working Draft.
[48] World Wide Web Consortium, James CLARK et Steve DEROSE (rédacteurs). XML Path Language (XPath), Version 1.0 (W3C Proposed recommendation).
[49] World Wide Web Consortium. Steve DEROSE et Ron DANIEL Jr. (rédacteurs) XML Pointer Language (XPointer). Working Draft.
[50] World Wide Web Consortium. Henry S. THOMPSON, David BEECH, Murray MALONEY et Noah MENDELSOHN (rédacteurs). XML Schema Part 1: Structures.
[51] World Wide Web Consortium. Paul V. BIRON et Ashok MALHOTRA (rédacteurs).
XML Schema Part 2: Datatypes.
[52] World Wide Web Consortium, Stephen DEACH (rédacteur). Extensible Stylesheet Language (XSL), Version 1.0 (W3C Working Draft).
[53] World Wide Web Consortium, James CLARK (rédacteur). XSL Transformations (XSLT), Version 1.0 (W3C Proposed recommendation).
. Une liste plus complète des différences entre SGML et XML se trouve à l’URL
TR/NOTE-sgml-xml et dans l’article de Sarra BEN LAGHA dans ce Cahier, page 127
. Des données de type « caractère » sont celles déjà traitées par le programme d’analyse (en anglais parser)et qui ne contiennentplus d’appelsd’entitésou de balises.Dansle jargon XML celas’appelleparsed character data ou données textuelles analysées et se note #PCDATA.
. Dans la DTD nous definissons (ligne 7) l’entité paramètre i18n contenant xml:lang. Puis l’entité paramètre i18n est incluse, ligne 8, dans l’entité paramètre basic. Celle-ci est associée dans la DTD à pratiquement tous les éléments (voir lignes 53, 55, 58, 60, etc.).
[4] . Les abréviations NC et NS représentent non-colon (sans deux points «: ») et namespace (domaine nominal).
[5] . Cette liste est en grande partie l’œuvre de Patrick ANDRIES et François YERGEAU et se trouve à l’URL .