Powered by |
Introduction à XSLTMichel CASABIANCA - casa@sweetohm.netCe document est une introduction à XSLT et constitue la deuxième partie d'un cycle de trois tutoriels sur XML. La première partie traite de XML et la troisième du développement XML en Java. Cet article n'a pas la prétention d'être exhaustif et s'il permet de se mettre le pied à l'étrier en moins d'une heure, il ne peut remplacer la lecture d'ouvrages de référence ou de la recommandation du W3 (voire bibliographie en fin de l'article). Tout commentaire concernant cet article (correction ou autre remarque) est le bienvenu. Un grand merci à Arnaud Storq pour ses corrections.
Présentation de XSLTransformationsXSLT (pour eXtensible Stylesheet Language, Transformation) est un langage de feuille de style pour XML. Il permet ainsi de transformer un document XML (avec un processeur XSLT) en un autre document, qui peut être un document XML (conforme à une autre DTD), un document HTML, LaTeX ou un document de tout autre format texte (par opposition à un format binaire). Dans la pratique, XSLT donne la pleine mesure de sa puissance lors de transformations de XML vers HTML ou XML. On l'utilise ainsi généralement pour:
Formatting ObjectsXSLT n'est en fait qu'une partie d'un standard plus vaste: XSL (pour eXtensible Stylesheet Language) qui comporte une autre partie qui définit les Formating Objects (cette partie du standard est appelée XSLFO). Comme leurs noms le laisse supposer, XSLT permet de transformer un document alors que XSLFO définit un jeu de balises pour la définition du formatage d'un document. XSLFO définit donc un format de documents comme PDF ou PostScript. Typiquement, le rendu d'un document en XSLFO suivra les étapes suivantes:
Figure 1: Transformation XSL-FO Ce document XSLFO peut alors être visualisé avec un programme compatible. Si XSLT est largement utilisé pour la transformation vers HTML et d'autres formats, les formating objects sont encore peu utilisés car le nombre de programmes permettant de visualiser de tels documents reste faible du fait de la jeunesse de la norme. Standards associésXSLT fait appel à d'autres standards de la nébuleuse XML:
XSLT étend XPath par un jeu de fonctions qui lui sont propres. La connaissance de ces standards est nécessaire à l'écriture de ces feuilles de style. Notions de baseNous allons maintenant définir les notions de base de XSLT sans prétendre à l'exhautivité (une section de référence des éléments XSLT suivra). Notion de TemplateXSLT est un langage dont la syntaxe est XML. Cela signifie qu'une feuille de style XSLT est un document XML bien formé. On ne peut cependant pas lui associer de DTD dans le cas général (et donc valider une feuille de style) car elle peut comporter des éléments (générés) qui ne sont pas définis dans le standard XSL. Commençons par un exemple simple de document. Soit l'article XML suivant:
Pour transformer cet article en document HTML, nous pourrions envisager la feuille de style suivante:
Cette feuille de style est très simple dans son principe:
Nous aurons retenu de cet exemple que le nom XSL Transform est amplement mérité ! La tache essentielle d'une feuille de style XSLT est en effet de transformer les éléments XML en autres chose (ici des éléments HTML). Pour indiquer au processeur XSLT les transformations à effectuer, nous utilisons des templates. Ce sont des déclarations (XSLT est un langage déclaratif) qui indiquent au processeur comment effectuer cette transformation. Par exemple, le template suivant:
Déclare les éléments du document source à intercepter dans l'attribut match. Ici nous souhaitons intercepter les éléments term que nous allons remplacer par des éléments HTML <i>. Pour ce faire, nous écrivons directement dans le fichier XSLT les éléments <i>. Comme leur espace de nommage n'appartient pas à celui de XSLT, le processeur sait qu'il doit les écrire tel quel dans le document résultant. D'autre part, l'élément <term> encadre du texte, donc il faut demander au processeur XSLT de traiter le contenu de l'élément du document XML. Cela est fait avec l'élément <xsl:apply-templates/>. <xsl:apply-templates/> demande au processeur de traiter les noeuds inclus (des noeuds texte ou des éléments). Le processeur recherche (dans l'ordre du document) les éléments qui correspondent à un template et leur applique. Par défaut, il n'est pas nécessaire de définir de template pour le texte (il est écrit dans le document produit en l'absence de template). Nous avons vu qu'une feuille de style XSLT est essentiellement une liste de templates et ces templates forment la base de la programmation XSLT. Cependant, ce type de développement déclaratif est assez inhabituel (on est plus habitué à des langages impératifs) et c'est la principale difficulté de XSLT. Expressions XPathComme nous l'avons vu ci-dessus, XPath est un standard XML utilisé par XSLT pour définir des chemins dans un fichier XML. Ces chemins sont en particulier utilisés dans l'attribut match des templates. En effet, pour déterminer s'il doit traiter un noeud donné, le processeur examine les expressions des attributs match et détermine s'ils s'appliquent à ces noeuds. L'expression XPath la plus simple (que nous avons déjà vue sans le savoir) est un simple nom de noeud. Par exemple, l'expression sect sélectionne les noeuds sect fils de l'élément courant. Il est aussi possible de décrire un chemin vers un noeud de la même manière que dans un système de fichiers (Unix). Par exemple, l'expression foo/bar sélectionne les éléments bar fils d'un noeud foo et petit fils du noeud courant. Dans le document d'exemple, l'expression sect/p appliquée à la racine du document (dans l'élément article) renvoie un ensemble de noeuds constitué des deux éléments p du document. Il est aussi possible de faire référence à la racine du document avec un slash (/) en début d'expression (comme dans un système de fichiers Unix). Par exemple, l'expression /article/sect sélectionne les éléments p du document. Il est aussi d'indiquer une position d'un élément. Par exemple l'expression XPath /article/sect[2] sélectionne la deuxième section du document. La partie entre crochets est appelée prédicat. L'exemple précédent est un cas particulier de prédicat qui porte sur la position, mais il est possible de placer dans le prédicat une expression logique qui opère une sélection des noeuds. Par exemple, l'expression /article/sect[title='Syntaxe de XSLT'] sélectionne la section par son élément titre. Jusqu'à présent, nous avons vu des expressions qui portent sur des éléments. Il est aussi possible de sélectionner des attributs en faisant précéder leur nom d'une arobase (@). Par exemple, l'expression @title sélectionne l'attribut title. Ainsi, pour sélectionner la section dont l'attribut title a pour valeur Syntaxe XSLT, on peut écrire sect[@title='Syntaxe XSLT']. Il est possible d'utiliser des opérateurs logiques dans des prédicats. Ainsi, sect[position()=1 or @title='Introduction'] renverra la section en première position ou dont l'attribut title a pour valeur Introduction. Au passage, nous avons une première fonction de XPath (la fonction position() qui renvoie la position d'un noeud). XPath définit un certain nombre de fonctions. Je ne vais pas les détailler ici, voir la section Références pour une liste exhaustive des fonctions de XPath (ainsi que des extensions définies par XSLT). Précisons enfin que certains attributs XSLT (comme l'attribut match de l'élément <xsl:template>) doivent contenir une expression XPath alors que d'autres n'en contiennent pas à priori. Pour forcer le processeur XSLT à interpréter le contenu d'un attribut comme une expression XPath, nous devons entourer l'expression d'accolades. Par exemple <img src="{@url}" alt="{@text}"> va placer des l'attribut src la valeur de l'attribut url et dans l'attribut alt celle de l'attribut text. Éléments XSLTNous allons maintenant passer en revue les principaux éléments XSLT. Importation de fichiersUne feuille de style peut parfois devenir complexe et l'on aura intérêt à la découper modules. Par exemple, on pourra placer dans un même fichier tous les templates relatifs au formatage du texte et dans une deuxième, tous ceux relatifs à la structure du document (table des matières, notes de bas de page). Pour importer une feuille de style dans une autre, on pourra utiliser une des syntaxes suivantes:
L'attribut href indique l'URI du fichier (qui peut être une URL ou un chemin dans le système de fichiers). Ces déclarations doivent être les premières d'une feuille de style. Les templates des fichiers importés ont une priorité inférieure à ceux du fichier dans lequel ils sont importés. On peut ainsi surcharger des templates dans le fichier qui importe des définitions. On peut changer cette règle de priorité dans le corps d'un template avec la déclaration <apply-imports> qui demande au processeur d'utiliser les définitions importées. Il est aussi possible de définir des priorités pour les templates avec l'attribut priority. Cet attribut doit avoir une valeur réelle. Une priorité de +1 assure que ce template sera toujours prioritaire par rapport aux templates sans priorité et une valeur de -1 que ce template ne sera jamais prioritaire. L'inclusion de template est un mécanisme beaucoup plus simple: tout se passe comme si le fichier inclus était copié. Les priorités des templates inclus sont identiques à celles de ceux du fichier ayant déclaré l'inclusion. Paramètres et variablesIl est possible de définir des variables dans un fichier XSLT à l'aide des déclarations suivantes:
On peut faire référence à une variable dans une expression XPath à l'aide de la forme $var. La portée d'une variable dépend de l'endroit où elle a été déclarée: si elle est déclarée dans la racine du document (sous l'élément <xsl:stylesheet>, elle est accessible de tout le document alors que si elle déclarée dans le corps d'un template, elle n'est accessible qu'à l'intérieur de celui-ci. On notera que la valeur d'une variable ne peut être modifiée (elles auraient pu avantageusement être appelées constant). On déclare un paramètre de la manière suivante:
On pourra ainsi passer la valeur de ce paramètre au processeur XSLT sur la ligne de commande. On peut alors faire référence à la valeur de ce paramètre de la manière suivante:
On pourra aussi appeler un template en lui passant un ou plusieurs paramètres de la manière suivante:
On notera que ce template ne comporte par d'attribut match, mais un attribut name à la place. Ce template se comporte alors comme une fonction (à laquelle on passe des paramètres). Boucles et testsIl est possible de boucler sur un ensemble de noeuds avec l'élément <for-each>. Par exemple, pour générer le bloc des notes de bas de page, on pourrait écrire:
L'élément <xsl:for-each> boucle sur les éléments note du document et les affiche (après avoir écrit leur numéro). Il est aussi possible d'effectuer des tests. La première possibilité est d'utiliser l'élément <xsl:if>. Par exemple:
Dans ce fragment, on teste l'existence d'un résumer et on l'affiche s'il existe. Il existe aussi l'équivalent d'un switch avec la forme suivante:
On commence par énumérer les cas possibles dans des éléments <when>, puis le cas par défaut dans un élément <otherwise>. Formats de sortieIl est possible de produire, à l'aide d'une feuille de style, des formats de sortie XML, HTML ou Texte. On doit déclarer le format de sortie d'une feuille de style à l'aide de l'élément <xsl:output>, placé sous l'élément <xsl:stylesheet>. Chacun de ces traite différemment les éléments XML ou les blancs:
Il est de plus possible d'indiquer au processeur XSLT de préserver les blancs à l'aide de l'élément <xsl:preserve-space elements="liste">. Pour finir, il est possible d'indiquer au processeur s'il doit indenter le document (XML ou HTML) résultant avec l'attribut indent="yes|no" de l'élément <xsl:output>. XPathXPath propose un jeu de fonctions et d'opérateurs pour exprimer des chemins dans un document XML. Nous avons déjà vu l'essentiel de la syntaxe XPath, reste à voir la notion d'axe. Les axes XPathJusqu'à présent, nous avons vu des expressions XPath de la forme foo dont le slash indique que l'élément foo est le fils de l'élément courant. On dit alors que l'on fait une recherche sur l'axe fils. On pourrait aussi vouloir rechercher un élément père de foo. Pour ce faire, on utilise une notation plus générale que sont les axes. Par exemple, pour rechercher un élément foo père de l'élément courant, on écrira:
On notera que cette notation est équivalente à:
Avec une notation de type système de fichier. XPath définit ainsi 13 axes de recherche:
Par exemple, pour rechercher les éléments <chapitre> après le noeud courant dans l'ordre du document, on écrira:
Pour rechercher le noeud ancêtre du noeud courant ayant pour ID foo, on notera:
Fonctions XPathXPath définit quatre types de base: les booléens (pouvant avoir pour valeur true ou false), les entiers, les réels et les chaînes. Les principales fontions définies sont les suivantes:
Par exemple, l'expression:
Renvoie le dernier élément chapitre frère de l'élément courant. Exemples de mise en oeuvreNous allons voir maintenant des exemples de mise en oeuvre de XSLT (dans le cadre de projets In Fusio). Sites des Éditions O'ReillyPourquoi XML et XSLT ?Le choix de XML nous a semblé le meilleur pour plusieurs raisons :
Choix techniquesLes informations pouvant être raisonnablement mises à jour quotidiennement, nous avons opté pour une solution de compilation statique des pages du site : les pages HTML sont générées à partir des sources XML puis envoyées au serveur. Il existe deux autres solutions :
ArchitectureLe site est généré entièrement à chaque compilation (pour éviter des problèmes de dépendances) à partir d'une arborescence de fichiers XML. Les fichiers de même type sont placés dans le même répertoire. Les types de fichiers sont au nombre de six :
Les pages d'index (la page d'accueil et les pages des catégories) sont générées par des fichiers XSL appliqués sur l'index XML du site : un fichier XML regroupant tous les fichiers XML des sources. Il est ainsi possible de générer les listes des ouvrages classées par ordre alphabétique, la liste des brèves classées par date, etc. Ainsi, la page d'accueil regroupe des fragments de nombre de fichiers XML :
Figure 2: Structure de la page d'accueil du site Les fichiers à l'origine des différentes zones de cette page sont les suivants :
Pour conclure, je dirais que XML permet de gérer un tel site de manière rationnelle et en préservant les investissements des Éditions O'Reilly du fait que XML est un standard et donc à l'abri du bon vouloir d'un unique éditeur de logiciel. WAP SDKLe WAP SDK permet aux développeurs de jeux d'accéder aux services de GameZilla mais aussi de rendre le code du jeu indépendant de la plateforme cible. En particulier, le WML des pages doit être adapté aux deux principaux navigateurs WML que l'on trouve sur les téléphones mobiles (Nokia et Phone.com) et traduites suivant la langue de l'utilisateur. Il est bien sûr possible de le faire dynamiquement en PHP mais cela imbrique la présentation et la logique du jeu (les templates pour les différentes versions du WML sont noyés dans le code) et est gourmand en ressources (pour obtenir dynamiquement les messages traduits, il faut aller les chercher dans une base de données, ce qui peut impliquer plusieurs requêtes par page). À cette approche dynamique, nous avons préféré une approche statique:
Le programme de jeu doit être accompagné d'un fichier XML contenant la traduction des messages et les noms des fichiers des images suivant leur taille (fichier de ressources). Il doit être aussi accompagné d'un descripteur indiquant les configurations supportées (navigateurs, langues et tailles d'images). Lors de la compilation, le compilateur du SDK génère N répertoires comportant les fichiers compilés. Un répertoire correspond à une configuration possible (par exemple, navigateur Nokia, français et grandes images). Prenons le cas d'une page d'accueil d'un jeu:
Cette page comporte les particularités suivantes:
Fichier pour la configuration Phone.com/fr/petites images:
Dans ce fichier, l'élément <menu> a été remplacé par <select> et les éléments <item> par des <option>. Les références à des ressources texte ont été remplacées par les messages en français et les références à des images par leur valeur pour les petites images. Le fichier généré pour la configuration phone.com/en/grandes images est le suivant:
Dans ce fichier, l'élément <menu> a été remplacé par une liste d'éléments <a href="">, les références à des ressources texte ont été remplacées par les messages en anglais et les références à des images par leur valeur pour les grandes images. Cette approche amène beaucoup de souplesse:
Administration ToolCet outil permet d'administrer le serveur de production. Il permet par exemple de gérer la base sans avoir à connaitre sa structure et se présente sous la forme d'une application JSP. Afin d'etre simple à utiliser, nous avons retenu une approche par wizard. Un wizard est ici une succession d'étapes pour réaliser une opération de maintenance sur le serveur. Par exemple:
Ce wizard XML est compilé en pages JSP avec une feuille de style XSLT. Par exemple, le wizard ci-dessus génère la page suivante:
Les écrans générés pour ce wizard sont les suivants: Step 1
Step 2
Step 3
Cette compilation XSLT permet ici de gagner en temps de développement des wizards. En effet, l'écriture de ces pages JSP serait très répétitive et propice aux erreurs. De plus, pour modifier l'interface ou une fontionnalité des JSPs, il suffit de modifier la feuille de style et de recompiler, les modifications sont alors automatiquement prises en compte dans toutes les pages. Dernière mise à jour : 2003-05-28 |