XSL

Un article de Agora2ia.


Sommaire

Introduction

Lorsque j'ai abordé XSL (eXtensible Stylesheet Language) pour la première fois, la majorité des ressources ne faisaient que lister de manière exhaustive les fonctions du langage. Il n'y avait pas d'autres solutions que de se « palucher » les quelques 99.10^99 fonctions, pour déceler celle qui pouvait répondre au mieux à mon problème parmi toutes celles potentiellement intéressantes.

Ce qui m'a manqué, c'est une vue d'ensemble des fonctionnalités (plus que des fonctions), et des conseils sur quelle solution mettre en place pour un problème donné.

Je vais donc essayer dans cet article de présenter les diverses techniques qu'offre XSL, au travers des réponses que j'ai pu trouver, mais aussi mon avis dans la mesure du possible, voire quelques indices ou astuces. Cela afin d’orienter au mieux les développements, et donc de mieux maîtriser la conception... Pour répondre à ces objectifs, je vais tout d’abord présenter XSL, en introduisant les mots clefs, pour ensuite aborder les outils et principes nécessaires à la réalisation de transformations XSL.

Ca me permettra de poursuivre sur des éléments permettant d’envisager des développements complexes avec sérénité, et de conclure en 3 actes, sur « les tenants et les aboutissants » (copyright SuperJemmi) du langage, les problématiques qu’il induit, et des intégrations potentielles dans des solutions d’envergure.

Quel programme !

Avant de continuer, je tiens à remercier mon « comité de relecture », à savoir Bobo, Cyp et Den’z.


Présentation

XSLT est donc un langage permettant d'extraire et de restructurer des informations, à partir d'un document XML, et souvent vers un autre document XML. Le langage de transformation XSLT fait l'objet d'une recommandation du W3C.

Pour rappel, un document XML (eXtensible Markup Language) est un fichier texte contenant des balises, un peu comme un fichier HTML, avec certaines spécificités :

  • toute balise doit être explicitement refermée,
  • toute balise fille doit être refermée avant sa balise mère (qui la contient),
  • les balises sont définies par l'utilisateur,
  • leur nomenclature est sensible à la casse.

Sachant cela, un document XML peut donc également être représenté sous la forme d'un arbre, où les embranchements, ou nœuds, sont les balises XML. La représentation sous forme textuelle est privilégiée dans un contexte de communication, de gestion de flux, alors que celle de l'arbre est plus commode dans un contexte de traitement, comme c'est le cas ici. On peut alors voir XSL comme un moyen de transformer cet arbre initial, en un autre arbre.... ou en un simple tas de feuilles ! En effet, le document résultat d'une transformation XSL peut être un autre document :

  • brut (texte),
  • imprimable (au format PDF grâce à XSL-FO),
  • internet (au format HTML, xHTML ou WML),
  • graphique (au format SVG),
  • multimédia (au format SMIL).

Enfin, si j'ai rappelé ces règles, c'est qu'une transformation XSLT se définie dans un fichier texte en utilisant le langage XSL qui est lui-même du XML, et suit donc les mêmes règles. Ce qui implique qu'il pourra être modifié lui-même par une feuille XSL, ou encore qu'il pourra être modifié par programmation avec tout langage possédant une interface DOM.

Avant de continuer, j'aimerais apporter une précision pour lever toute ambiguïté. On entend souvent parler, et on mélange parfois, les acronymes XSL, XSLT et XSL-FO.

  • La pluspart du temps, on utilise XSL pour ré-arranger l'arbre XML d'origine, déplacer des feuilles, les regrouper, et sélectionner certains de leurs attributs, afin d'obtenir par exemple à partir d'une liste XML de DVD, une page HTML avec tout d'abord l'ensemble des titres, puis en dessous la description de chaque DVD. Dans ce cas, on parle bien de transformation (le T de XSL-T), et on la réalise à l'aide de la recommandation XSL Transformations. On peut alors utiliser une autre technologie de feuilles de styles, complémentaire, à savoir CSS, pour assurer un rendu plus fin.
  • Par contre, lorsque l'on veut vraiment maîtriser le rendu final, au pixel près, à des fins d'impressions par exemple, dans ce cas il faut utiliser des feuilles de style d'objets de formatage, ou XSL Formatting Objects (XSL-FO), ou encore Recommendation XSL, pour générer par exemple un document PDF.


Le minimum vital

Le but ici est de présenter les fonctionnalités XSL de base permettant d'écrire et de mettre en oeuvre des transformations simples, à partir d'un document XML.

Un tigre dans le moteur

Afin de donner vie à ce fichier texte, inerte, on doit utiliser un moteur, un processeur XSLT, auquel on fournit le fichier XML d'entrée, le document XSL qui spécifie les transformations à apporter, et éventuellement le nom du fichier à générer.

Un descriptif, voir un comparatif des processeurs XSLT disponibles pouvant à lui seul faire l'objet d'un article, je ne vais citer que les trois que j'ai utilisés, à savoir :

  • Saxon, qui est assez "bavard" (ce qui peut être assez pratique en debug),
  • Xalan (en version Java ou C++), moins bavard, et donc plus performant,
  • et enfin MSXML, le MS étant pour Microsoft.

L'avantage de ce dernier, est qu'il est livré en standard avec Windows, et intégré à Internet Explorer. Le résultat est qu'il suffit d'indiquer le chemin d'accès au document XSLT (<?xml-stylesheet type="text/xsl" href="MA_TRANSFORMATION.XSL"?> [1]) en début du fichier XML, puis d'ouvrir ce dernier avec IE pour visualiser directement le résultat de la transformation, sans autres outil, installation ou manipulation particulière.

Exemple de fichier XML :

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="MA_TRANSFORMATION.XSL"?> 
<document>
   <title>XSL</title>
   <chapter>
      <title>Introduction</title>
      <para>Bla bla bla...</para>
   </chapter>
</document>


XmlSpy : l'espion qui aimait XML

Quel que soit le langage, tout développeur a souvent un IDE de prédilection. Pour ma part, pour travailler sur XML-XSL, j'ai utilisé XmlSpy de la société Altova qui fournit divers outils pour travailler sur XML.

Il s'agit d'un IDE orienté XML, et ses technologies connexes (HTML, DTD et SchemaXml, XSL...), aux fonctionnalités diverses et variées...


Pour les fonctionnalités XSL, XmlSpy permet notamment :

  • de choisir le processeur XSLT à utiliser parmi celui fourni par d'XmlSpy lui-même, celui de Microsoft, ou encore un script de lancement (tolérant ainsi n’imposte quel processeur).
  • Mais la cerise sur le gâteau des fonctionnalités, est assurément le debugger XSL. Comme tout debugger, il permet de poser des points d'arrêt, de parcourir le code à mesure de l'exécution, d'obtenir alors la valeur de variables XSL.


Seule ombre au tableau : il vous faudra disposer d'une importante résolution d'écran, comme pour tout IDE multi-fenêtres. Mais cela est d'autant plus vrai que le langage considéré (XML) est ici très verbeux (oubliez la sacro-sainte "ligne de 80 caractères"). De plus, par défaut, le mode debug s'ouvre avec 3 fenêtres en mosaïque : le document XML d'entrée, le XSL de transformation et le HTML de sortie. Il faudra également prévoir une machine puissante pour subvenir aux besoins que nécessite le traitement d'un langage verbeux (décidément).


Il existe une "Home Edition", gratuite depuis la version 2004, mais déjà très utile. Depuis la version 2005, chacune des versions peut être intégrée sous forme de plugin aux principaux EditeurIntegres du marché, et notamment Eclipse. Pour un liste détaillée et comparée des fonctionnalités des différentes versions, reportez vous à la matrice disponible sur leur site, pratique et bien faite.


Pour plus d'informations sur cet éditeur, voir la page sur XmlSpy.

Les 3 règles par défaut

Tout d'abord, il faut avoir conscience des trois règles par défaut qui, soit vous permettront avec un fichier XSL vide d'extraire l'intégralité du texte d'un fichier document XML, soit vous amèneront à rencontrer des situations inattendues si vous n'y prenez pas garde.

En effet, XSL définit un trio de règles qui sont appliquées quand aucune des règles que vous avez écrites n'est sélectionnée, et donc à fortiori lorsque le fichier XSL est vide.

Fichier XSL minimal (vide) :

<?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>


Fichier XSL équivalent (règles par défaut) :

<?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:template match="/ | *">
      <xsl:apply-templates/>
   </xsl:template>

   <xsl:template match="text() | @*">
      <xsl:value-of select="."/>
   </xsl:template>

   <xsl:template match="processing-instruction() | comment()"/>

</xsl:stylesheet>


La première règle par défaut [1], s'applique au nœud racine et à tout autre nœud : elle déclenche un appel de règle dessus. La second [2], s'applique à tout nœud de type texte (à tout contenu textuel) et à tous les attributs de nœud : elle affiche alors leur valeur. La troisième et dernière règle par défaut [3], s'applique aux instructions de traitement et aux commentaires, pour lesquels elle ne fait rien.

Une des principales conséquences de ces règles, est de penser à inhiber toute balise que l'on ne souhaite pas voir afficher, soit parce que l'on ne souhaite pas la voir dans le document généré, soit parce qu'elle est gérée dans une autre règle...

Ainsi, si l'on souhaite interdire l'affichage d'une balise <copyright>, qui est traitée par ailleurs, il faudra penser à l'inhiber de la sorte :

<xsl:template match="copyright"/>

Mais nous y reviendrons...


XPath : le SQL pour XML

L'observation de ces règles nous permet d'entrevoir le rôle et l'intérêt de XPath.

En une phrase, XPath est à XML ce que SQL est aux bases de données, à savoir un langage pour écrire des requêtes, mais uniquement de recherche en ce qui concerne XML. Tout comme XSLT, XPath fait l'objet d'une spécification, distincte, du W3C.

Une expression XPath, encore appelée chemin de localisation XPath, est constituée d'une ou plusieurs étapes de localisation XPath, séparées entre elles par le symbole '/'. Chacune de ces étapes de localisation pouvant elle-même être constituée dans l'ordre :

  1. un axe (par défaut l'axe implicite est child), qui permet d'indiquer si l'on remonte vers les parents, ou si l'on s'enfonce vers les enfant, suivi du séparateur ::, suivi de
  2. un test de nœud, qui spécifie un nœud ou un ensemble de nœuds (test portant sur un d'élément, d'attribut, de namespace ou sur un joker), suivi de
  3. zéro à n prédicats, encadrés chacun par [ ], qui ajoutent des restrictions supplémentaires aux chemins.

Le langage XPath peut être utilisé dans sa forme développée ('parent' pour remonter au nœud père), ou abrégée ('..' toujours pour remonter au nœud père). Dans sa forme abrégée, une expression XPath ressemble alors au chemin, au 'path', d'un fichier sur le disque dur de l'ordinateur.

Si l'on représente un document XML et ses balises entrelacées comme un arbre de dépendances, une expression XPath est une énigme pour laquelle l'enquêteur (le processeur XSLT) peut trouver des solutions diverses en qualité et en quantité, mais qui correspondent tout à fait aux indices qu'il a à sa disposition. L'évaluation de l'expression (résolution de l'énigme) peut donner comme résultat, soit une valeur (numérique ou alphanumérique), soit un sous-ensemble des nœuds de l'arbre.

On peut utiliser une expression XPath à divers endroits du code XSL :

  1. Désignation des nœuds auxquels s'applique une règle (comme ci-dessus, pour les règles par défaut) : <xsl:templates select="FILM/TITRE"/>...<xsl:templates> pour définir une règle qui s'applique à toute balise TITRE, fille d'une balise FILM, elle-même fille de la balise sur laquelle on travaille,
  2. Sélection de nœuds auxquels on souhaite appliquer une règle : <xsl:apply-templates select="//CINEMA[VILLE='Montgeron']/SALLE"/> pour propager l'appel de règle à toute balise SALLE fille d'une balise CINEMA dont la balise fille VILLE vaut 'Montgeron', quel que soit l'endroit où se trouve cette balise CINEMA dans le document XML,
  3. Extraction des valeurs : <xsl:value-of select="../SALLE/@NO"/> pour obtenir la valeur de l'attribut NO de toute balise SALLE qui se trouve au même niveau que la balise sur laquelle on travaille,
  4. Prédicats de test : <xsl:if test="$titre='' and TITRE=$titre">...<xsl:if> pour effectuer un traitement que lorsque l'on a une balise TITRE, fille de la balise sur laquelle on travaille, égale au paramètre titre que l'on a et qui ne doit pas être une chaîne vide.

Enfin, pour maîtriser les expressions XPath, il est important de bien distinguer le nœud courant du nœud contextuel. Le nœud courant est celui dans lequel on est quand on commence à lire l'expression XPath, celui qui est à l'origine de cette expression. Le nœud contextuel quant à lui, est la cible, le ou les nœuds résultats successifs.

Pour plus de détails, et notamment la liste exhaustive des symboles et des spécificateurs d'axe, vous pouvez vous reporter au paragraphe intitulé "chemin de localisation ou motifs XPath" du tutoriel Comprendre XSLT.

Vous pouvez aussi voir la page XPath.


La règle est de rigueur

Paramètre et variable constants

Lorsque j'ai approché XSL, je suis tombé sur deux notions que j'ai eues du mal à distinguer : xsl:variable et xsl:param.

Tout d'abord, pour être clair, comme son nom de l'indique pas, une variable est... constante, tout comme les paramètres. Une fois instanciée dans une règle, éventuellement à la racine, sa valeur ne peut être modifiée, et on ne peut définir une autre variable portant le même nom dans la même portée. Pour définir une variable qui contiendrait le nom du CINEMA de la ville de Montgeron :

<xsl:variable name="nomCinema" select="CINEMA[VILLE='Montgeron']/NOM"/>

Dans le cas où la valeur de la variable devrait être un peu plus élaborée, comme le reformatage du nom du cinéma, pour par exemple mettre l'article éventuel à la fin entre parenthèses, on peut définir la valeur de la variable en appelant une fonction ainsi :

<xsl:variable name="nomCinema"><xsl:call-template name="formateNomCinema"/></xsl:variable>

Dans tous les cas, l'appel à une variable s'effectue de la sorte :

Mon cinéma préféré est le <xsl:value-of select="$nomCinema"/> car l'ambiance y est...

Par extension (abusive ?), tout ce qui vient d'être dit pour une variable fonctionne avec un paramètre : le code ci-dessus conservera le même comportement si l'on remplace xsl:variable par xsl:param.


Par contre, les paramètres ont deux autres utilisations où ils sont irremplaçables.


La première est le passage de paramètres à la feuille XSL lors de l'appel au processeur, afin de disposer dans le XSL d'informations inaccessibles pendant la transformation, amis disponibles dans l'environnement d'appel (ligne de commande, programme...). Très pratique si l'on veut faire apparaître dans le document généré, le login de celui qui l'a généré, ou encore la date de la transformation, la date courante n'étant pas accessible en XSL standard. Pour cela, il suffit de :

  1. définir au début du document XSL le paramètre, avec un nom, et éventuellement une valeur par défaut,
  2. et d'indiquer le nom et la valeur du paramètre lors de l'appel au processeur XSL (si cette étape est omise, volontairement ou non, le paramètre prendra alors la valeur par défaut dans le document XSL).

Cet appel étant propre à chaque processeur, je vous indique en exemple l'appel au processeur Xalan-J, et vous laisse vous reporter à la documentation de votre propre processeur XSL.

Exemple d'appel en ligne de commande avec la date courante en paramètre :

java org.apache.xalan.xslt.Process -IN foo.xml -XSL foo.xsl -OUT foo.out -PARAM buildDate %DATE%


Instruction XSL pour récupérer cette date dans la transformation

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="buildDate">INCONNUE</xsl:param>

</xsl:stylesheet>


L'autre utilisation, est le passage de paramètre à une règle cette fois...


TODO

Plugins Eclipse


Ressources

Sites

  • Un très bon tutoriel en français pour Comprendre XSLT.
  • Un autre bon site en français est celui de laltruiste.com sur Le langage XSL qui lui énumère toutes les fonctions.
  • Ce Tutorial XSL, en français, offre une vision plus large du langage.
  • EXSLT.org, le site officiel des extensions XSLT.
  • XSLTUnit.org, pour les tests unitaires XSLT.
  • Sans oublier XmlFr.org, l'incontournable référence en français concernant XML : son actualités et ses technos.


Livres

  • Comprendre XSLT (2001) de Philippe Rigaux aux éditions O'reilly France. Très bon livre pour débuter, qui présente l'ensemble des fonctionnalités du langage.
  • XSLT en action (2003) de Mangano aux éditions O'reilly France. Très bon livre pour approfondir et maîtriser XSLT par la pratique, au travers une quinzaine de cas d'utilisation concrets.
  • XSLT fondamental : Avec 20 design patterns prêts à l'emploi (2002) de Philippe Drix aux éditions Eyrolles.