Cours de XML - Mise en forme à l'aide de feuilles de style XSL : instructions XSLT

version 1.51, dernière mise à jour le 15 février 2011.

   

Table des matières (TdM)

  1. I. Les expressions de sélection
    1. Introduction
    2. Sélection d'éléments et d'attributs
      1. Sélection d'élément, syntaxe de base
      2. Sélection d'élément, appel de fonctions
      3. Sélection d'élément et DOM
      4. Sélection d'attributs
      5. Opérateurs logiques
  1. II. XPath
    1. Introduction
    2. Chemin de localisation
      1. Introduction
      2. Axes
      3. Prédicats
      4. Syntaxe non abrégée
      5. Syntaxe abrégée
    3. Fonctions de base
      1. Généralités
      2. Manipulation de nœuds
      3. Manipulation de chaînes de caractères
      4. Manipulation de booléens
      5. Manipulation de nombres
  1. III. Éléments XSLT
    1. Généralités
      1. Introduction
      2. Rappel : prologue d'un document XSL
    2. Les fondamentaux
      1. Généralités
      2. xsl:stylesheet
      3. xsl:output
      4. xsl:template
      5. xsl:value-of
    3. Ajout d'éléments et d'attributs
      1. xsl:element
      2. xsl:attribute
      3. Syntaxe courte
    4. Gestion des boucles
      1. xsl:for-each
      2. xsl:sort
      3. xsl:number
    5. Conditions de test
      1. xsl:if
      2. xsl:choose
    6. Variables et paramètres
      1. Introduction
      2. Élément xsl:variable
      3. L'élément xsl:call-template
      4. Les éléments xsl:param et xsl:with-param
      5. Exercice : Utilisation d'éléments XSL
  1. IV. Conception modulaire des feuilles de style
    1. Introduction
    2. Utilisation des templates
      1. Introduction
      2. Exemple
    3. Inclusions de feuilles de style

Retour au menu

Contenu du cours

I. Les expressions de sélection

1. Introduction

Connues en anglais sous le nom de XSL patterns, les expressions de sélection sont des chaînes de caractères qui permettent de sélectionner des nœuds dans un document source. Il est également possible d'utiliser une syntaxe spéciale, appelée XPath , qui permet de faire référence à des éléments et/ou des attributs en se fondant sur la structure arborescente du document XML (le Document Object Model -DOM).

>Retour à la TdM

2. Sélection d'éléments et d'attributs

a. Sélection d'élément, syntaxe de base

L'exemple le plus simple d'expression de sélection est le nom d'un type d'élément. Cette expression sélectionne tous les éléments du type précisé descendant ou ancêtre d'un nœud donné. Exemple :

<xsl:value-of select="nom_element" />

Considérons par exemple le fichier XML suivant, l’élément courant étant l’élément racine A :

<A>
  <B> <C>C1</C> </B>
  <B> <C>C2</C> </B>
  <D> <C>C3</C> </D>
  <E> <B> <C>C4</C> </B> </E>
  <B> <E> <C>C5</C> </E> </B>
</A>

b. Sélection d'élément, appel de fonctions
c. Sélection d'élément et DOM

On peut aussi « naviguer » dans les branches de l'arborescence du document XML, en utilisant les ressources du DOM. Différents types de syntaxes sont possibles, fondées sur une expression de la forme Element[Expression]. Par exemple :

Par exemple, l'expression section/paragraphe[last-of-type() and first-of-type()] sélectionne les éléments paragraphe fils uniques dont le père est un élément section ; l'expression section/paragraphe[last-of-any() and first-of-any()] sélectionne les éléments paragraphe dont le père est un élément section qui ne contient qu'un seul élément paragraphe.

La fonction ancestor() permet la sélection d'un ancêtre du nœud courant. Elle reçoit en argument une expression de sélection et recherche le premier ancêtre du nom correspondant à la sélection. Par exemple, ancestor(chapitre)/titre sélectionne l'élément titre du chapitre contenant l'élément courant.

d. Sélection d'attributs

Les attributs d'un élément sont sélectionnés en faisant précéder leur nom par le caractère @. Les règles relatives à la sélection des éléments s'appliquent également aux attributs :

Si l'on veut afficher le contenu de l'attribut, on le fait précéder du caractère /. Par exemple, <xsl:value-of select="paragraphe/@titre" /> permet l'affichage du titre de l'élément paragraphe fils de l'élément courant (si rien n'est précisé, par défaut il s'agit du premier élément paragraphe fils).

e. Opérateurs logiques

Les opérateurs logiques not(), and et or peuvent être utilisés, comme par exemple section[not(@titre)], qui sélectionne les éléments section qui n'ont pas d'attribut titre. Attention : lorsque, dans la DTD par exemple, l'attribut est défini comme ayant une valeur par défaut, même s'il n'est pas explicité dans le document XML, il est considéré comme existant.

>Retour à la TdM

II. XPath

1. Introduction

Comme son nom l'indique, XPath est une spécification fondée sur l'utilisation de chemin d'accès permettant de se déplacer au sein du document XML. Dans ce but, un certain nombre de fonctions ont été définies. Elles permettent de traiter les chaînes de caractères, les booléens et les nombres.

Le XPath établit un arbre de nœuds correspondant au document XML. Les types de nœuds peuvent être différents : nœud d'élément, nœud d'attribut et nœud de texte. En vue d'une utilisation plus aisée, le XPath comprend un mécanisme qui associe à tous ces types une chaîne de caractères.

La syntaxe de base du XPath est fondée sur l'utilisation d'expressions. Une expression peut s'appliquer à quatre types d'objets :

Chaque évaluation d'expression dépend du contexte courant. Une des expressions les plus importantes dans le standard XPath est le chemin de localisation. Cette expression sélectionne un ensemble de nœuds à partir d'un nœud contextuel.

>Retour à la TdM

2. Chemin de localisation

a. Introduction

Un chemin de localisation peut être de type absolu ou relatif.

La syntaxe de composition d'un chemin de localisation peut être de type abrégé ou non abrégé. Toute syntaxe non abrégée ne trouve pas forcément d'équivalent en syntaxe abrégée.

Un chemin de localisation est composé de trois parties :

Par exemple, dans le chemin child::section[position()=1], child est le nom de l'axe, section le type de nœud à localiser (élément ou attribut) et [position()=1] est un prédicat. Les doubles :: sont obligatoires.

La syntaxe d'une localisation s'analyse de gauche à droite. Dans notre cas, on cherche dans le nœud courant, un nœud section qui est le premier nœud de son type.

b. Axes
c. Prédicats

Le contenu d'un prédicat est une prédiction. Chaque expression est évaluée et le résultat est un booléen.

Par exemple, section[3] est équivalent à section[position()=3].

Ces deux expressions entre crochets sont équivalentes : chacune d'entre elles produit un booléen. Dans le premier cas, il n'y a pas de test, on sélectionne simplement le troisième élément, l'expression est obligatoirement vraie. Dans le second cas, un test est effectué par rapport à la position de l'élément section ; lorsque la position sera égale à 3, l'expression sera vraie.

d. Syntaxe non abrégée
e. Syntaxe abrégée

Cette syntaxe recoupe en fait la « syntaxe de base » vue plus haut. Elle permet d'obtenir des expressions du type para[@type="avertissement"][5], qui sélectionne le cinquième enfant de l'élément para, parmi ceux qui ont un attribut type ayant la valeur avertissement.

>Retour à la TdM

3. Fonctions de base

a. Généralités

De nombreuses fonctions peuvent être utilisées. Ces fonctions concernent quatre catégories d'objets : nœuds, chaînes de caractères, booléens et nombres. Chaque fonction peut avoir zéro ou plusieurs arguments. Dans les descriptions suivantes, lorsqu'un élément est suivi du caractère ?, cela signifie qu'il est optionnel. Cette liste est loin d'être exhaustive. Le chapitre suivant présente les fonctions XPath de manière plus complète.

b. Manipulation de nœuds
c. Manipulation de chaînes de caractères

Beaucoup de fonctions existent. Citons pour mémoire notamment :

d. Manipulation de booléens

Outre la fonction logique not(), ainsi que les fonctions true() et false(), une fonction utile est lang(chaine). Elle teste l'argument chaine par rapport à l'attribut xml:lang du nœud contextuel ou de son plus proche ancêtre dans le cas où le nœud contextuel ne contient pas d'attribut de ce type. La fonction retourne true si l'argument est bien la langue utilisée ou si la langue utilisée est un sous-langage de l'argument (par exemple, en//us). Sinon elle retourne false.

e. Manipulation de nombres

Voici quelques fonctions de manipulations de nombres :

>Retour à la TdM

III. Éléments XSLT

1. Généralités

a. Introduction

Dans cette partie, nous allons détailler quelques éléments XSLT et présenter des exemples d'utilisation. Ne sera introduite ici qu'environ la moitié des éléments de formatage XSLT ; libre à vous de vous renseigner sur les éléments manquants.

Le nom de domaine utilisé pour les exemples est celui de la spécification 1.0 : http://www.w3.org/TR/xslt. La spécification XSLT 2.0 a été publiée en janvier 2007, mais les modifications qu'elle introduit sortent du cadre restreint de ce cours.

b. Rappel : prologue d'un document XSL

Un fichier XSL doit commencer par les lignes indiquant le numéro de version XML et l'encodage de caractères utilisé :

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

>Retour à la TdM

2. Les fondamentaux

a. Généralités

Sont présentés ici les éléments de base du document XSL, ceux que l'on retrouve dans l'immense majorité des cas, voire la totalité pour certains.

b. xsl:stylesheet

Cet élément doit être l'élément racine du document XSL, et en tant que tel doit figurer juste après le prologue (et les commentaires éventuels qui suivraient celui-ci). Il contient tous les autres éléments de mise en forme. Dans le cas général, l'utilisation de cet élément est de la forme :

<xsl:stylesheet id="id" version="nombre" xmlns:pre="URI"> (...) </xsl:stylesheet>

id est l'identifiant unique de la feuille de style. version est le numéro de version de la feuille de style XSLT. À l'heure actuelle, la version peut être 1.0, 1.1 ou 2.0. xmlns:pre correspond à la définition de l'espace de noms. pre indique le préfixe qui sera utilisé dans la feuille de style pour faire référence à l'URI de l'espace nominal. Exemples :

<xsl:stylesheet version="1.0" xmlns:xsl="uri:xsl"> (...) </xsl:stylesheet>

... permet d'avoir accès uniquement à des fonctions de base.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> (...) </xsl:stylesheet>

... permet d'avoir accès à des fonctions évoluées d'XSLT. C'est cette déclaration que nous allons utiliser dans la suite.

c. xsl:output

Cet élément vide, à placer comme premier enfant de xsl:stylesheet, permet de spécifier des options concernant l'arbre de sortie. L'utilisation de cet élément est de la forme :

<xsl:output method="xml | html | text" version="nmtoken" encoding="chaine" omit-xml-declaration="yes | no" standalone="yes | no" doctype-public="chaine" doctype-system="chaine" cdata-section-elements="elt" indent="yes | no" media-type="chaine" />

Par exemple :

<xsl:output method="html" version="html4.01" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" />

... permet d'indiquer que le fichier de sortie sera au format HTML 4.01, conforme à la DTD publique de l'HTML du W3C, et que le jeu de caractères utilisé est l'ISO-8859-1. Le résultat en sortie est un fichier HTML commençant par

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

... et possédant dans son head

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />

L'utlisation d'un tel élément permet donc de se dispenser de la spécification explicite du codage de caractères via un élément <meta> lors de l'écriture de la feuille de style XSL.

d. xsl:template

Cet élément définit un modèle à appliquer à un nœud et à un contexte spécifiques. L'utilisation de cet élément est de la forme :

<xsl:template name="nommodele" match="expression" mode="modemodele"> </xsl:template>

Nous reviendrons plus loin sur les possibilités qu'offre cet élément pour une conception modulaire de la feuille de style.

e. xsl:value-of

Cet élément permet d'insérer la valeur d'un nœud dans la transformation. Ce nœud est évalué en fonction d'une expression. Cette expression peut correspondre à un élément, à un attribut ou à tout autre nœud contenant une valeur. L'utilisation de cet élément est de la forme :

<xsl:value-of select="expression" disable-output-escaping="yes | no" />

>Retour à la TdM

3. Ajout d'éléments et d'attributs

a. xsl:element

Cet élément insère un nouvel élément dans la transformation. Le nom de l'élément est donné par l'attribut name. L'utilisation de cet élément est de la forme :

<xsl:element name="nomelement" use-attribute-sets="jeuattr"> </xsl:element>

name correspond au nom de l'élément à créer. use-attribute-sets correspond au jeu d'attributs à associer à l'élément créé. Par exemple :

<xsl:element name="p"> <xsl:value-of select="texte" /> </xsl:element>

... permet de créer dans le fichier HTML un élément de paragraphe renfermant le contenu de l'élément texte du document XML.

b. xsl:attribute

Cet élément définit un attribut et l'ajoute au dernier élément actuellement ouvert dans le résultat de la transformation. Son utilisation est de la forme :

<xsl:attribute name="nom">valeur</xsl:attribute>

name correspond au nom de l'attribut à ajouter dans le contexte courant. valeur correspond à la valeur à lui donner. Par exemple :

<image> <xsl:attribute name="src">test.gif</xsl:attribute> </image>

... permet d'ajouter à l'élément image l'attribut src et de lui affecter la valeur test.gif, ce qui a pour effet de produire en sortie l'élément suivant :

<image src="test.gif"> </image>

On aurait pu, de manière tout à fait équivalente, écrire

<xsl:element name="image"> <xsl:attribute name="src">test.gif</xsl:attribute> </xsl:element>

... ce qui a pour effet de produire en sortie

<image src="test.gif"> </image>

c. Syntaxe courte

Il est possible de créer des éléments de manière plus compacte, à l'aide d'une syntaxe particulière. Supposons par exemple que nous ayons dans un fichier XML l'élément <image source="test.gif" texte_alternatif="Image de test"/>, et que nous souhaitions obtenir dans le fichier de sortie l'élément <img src="test.gif" alt="Image de test"/>. Il existe deux manières :

  1. La syntaxe longue, avec...

    <xsl:element name="img"> <xsl:attribute name="src"> <xsl:value-of select="@source" /> </xsl:attribute> <xsl:attribute name="alt"> <xsl:value-of select="@texte_alternatif" /> </xsl:attribute> </xsl:element>

  2. La syntaxe courte, utilisant des accolades...

    <img src="{@source}" alt="{@texte_alternatif}" />

La seconde syntaxe est plus compacte ; mais elle présente deux inconvénients :

>Retour à la TdM

4. Gestion des boucles

a. xsl:for-each

Cet élément de bouclage, que l'on a déjà rencontré, crée une boucle dans laquelle sont appliquées des transformations. Son utilisation est de la forme :

<xsl:for-each select="jeunœud"> </xsl:for-each>

select correspond au jeu de nœuds devant être parcouru par la boucle. Exemple d'utilisation :

<ul>
  <xsl:for-each select="item">
    <li> <xsl:value-of select="." /> </li>
  </xsl:for-each>
</ul>

b. xsl:sort

Cet élément permet d'effectuer un tri sur un jeu de nœuds. Il doit être placé soit dans un élément xsl:for-each soit dans un élément xsl:apply-templates. C'est un élément vide qui peut être appelé plusieurs fois pour effectuer un tri multicritères. Chaque appel à cet élément provoque un tri sur un champ spécifique, dans un ordre prédéfini. L'utilisation de cet élément est de la forme :

<xsl:sort select="nœud" data-type="text | number | elt" order="ascending | descending" lang="nmtoken" case-order="upper-first | lower-first" />

Par exemple :

<ul>
  <xsl:for-each select="livre">
    <xsl:sort select="auteur" order="descending" />
    <li> <b> <xsl:value-of select="auteur" /> </b> <br /> <xsl:value-of select="titre" /> </li>
  </xsl:for-each>
</ul>

Dans cet exemple, la liste des livres est classée dans l'ordre alphabétique décroissant des noms d'auteur.

c. xsl:number

Cet élément permet d"insérer un nombre formaté pouvant servir de compteur. L'utilisation de cet élément est de la forme :

<xsl:number level="single | multiple | any" count="nœud" from="nœud" value="expression" format="chaine" lang="nmtoken" grouping-separator="car" grouping-size="nombre" />

Exemple d'utilisation :

<ul>
<xsl:for-each select="livre">
  <xsl:sort select="auteur" />
  <xsl:number level="any" from="/" format="1." />
  <li> <b> <xsl:value-of select="auteur" /> </b> <br /> <xsl:value-of select="titre" /> </li>
</xsl:for-each>
</ul>

>Retour à la TdM

5. Conditions de test

a. xsl:if

Cet élément permet la fragmentation du modèle dans certaines conditions. Il est possible de tester la présence d'un attribut, d'un élément, de savoir si un élément est bien le fils d'un autre, de tester les valeurs des éléments et attributs. L'utilisation de cet élément est de la forme :

<xsl:if test="condition">action</xsl:if>

test prend la valeur 1 ou 0 suivant le résultat de la condition (vrai ou faux). action correspond à l'action devant être effectuée (texte à afficher, second test, gestion de chaîne...). Exemples d'utilisation : <xsl:if test="@âge=’24’>Cette personne a 24 ans.</xsl:if>, ou :

<xsl:if test="livre">
  <ul>
    <xsl:for-each select="livre">
      <li>
        <b> <xsl:value-of select="auteur" /> <br /> </b>
        <xsl:value-of select="titre" />.<xsl:if test="@langue='français'">Ce livre est en français.</xsl:if>
      </li>
    </xsl:for-each>
  </ul>
</xsl:if>

Dans le code précédent, si l'attribut langue de l'élément livre vaut français, le processeur ajoutera au fichier de sortie la phrase "Ce livre est en français". Il ne se passe rien si ce n'est pas le cas.

b. xsl:choose

Cet élément permet de définir une liste de choix et d'affecter à chaque choix une transformation différente. Chaque choix est défini par un élément xsl:when> et un traitement par défaut peut être spécifié grâce à l'élément xsl:otherwise. Exemple d'utilisation :

<ul>
  <xsl:for-each select="livre">
    <li>
      <b> <xsl:value-of select="auteur" /> <br /> </b>
      <xsl:value-of select="titre" />
      <xsl:choose>
        <xsl:when test="@langue='francais'">Ce livre est en français.</xsl:when>
        <xsl:when test="@langue='anglais'">Ce livre est en anglais.</xsl:when>
        <xsl:otherwise>Ce livre est dans une langue non répertoriée.</xsl:otherwise>
      </xsl:choose>
    </li>
  </xsl:for-each>
</ul>

>Retour à la TdM

6. Variables et paramètres

a. Introduction

Il est possible en XSLT de définir des variables et des paramètres permettant de faire des calculs. Il est nécessaire pour cela de faire appel à deux éléments XSL : xsl:variable et xsl:param.

b. Élément xsl:variable

L'élément xsl:variable sert à créer les variables dans XSLT. Il possède les attributs suivants :

Par exemple :

<xsl:variable name="nombre_livres" select="255" />
<xsl:variable name="auteur" select="'Victor Hugo'" />
<xsl:variable name="nombre_pages" select="livre/tome/@page" />

On notera la présence des guillemets imbriqués quand il s'agit d'affecter une chaîne de caractères à une variable.

La portée d'une variable est limitée aux éléments-frères et à leurs descendants. Par conséquent, si une variable est déclarée dans une boucle xsl:for-each ou un élément xsl:choose ou xsl:if, on ne peut s'en servir en-dehors de cet élément.

Une variable est appelée en étant précédée du caractère $ : <xsl:value-of select="$nombre_pages" />.

On peut utiliser une variable pour éviter la frappe répétitive d'une chaîne de caractères, et/ou faciliter la mise à jour de la feuille de style.

c. L'élément xsl:call-template

L'élément xsl:template peut être appelé indépendamment d'une sélection d'un nœud. Pour cela, il faut renseigner l'attribut name, et l'appeler à l'aide de l'élément xsl:call-template. Par exemple

<xsl:template name="separateur">
  <hr />
  <img src="ligne.gif" alt="séparation" width="150" height="2" />
  <hr />
</xsl:template>

Il suffit alors de l'appeler avec <xsl:call-template name="separateur"/>.

d. Les éléments xsl:param et xsl:with-param

Les paramètres créés avec ces deux éléments sont habituellement utilisés dans les modèles nommés, que nous venons de voir. Ils permettent de passer des valeurs aux modèles. Un paramètre est créé avec l'élément <xsl:param>, et passé à un modèle avec l'élément xsl:with-param. Les deux ont deux attributs :

Par exemple, on peut imaginer un template permettant d'évaluer le résultat d'une expression polynômiale :

<xsl:template name="polynome">
  <xsl:param name="variable_x" />
  <xsl:value-of select="2*$variable_x*$variable_x+(-5)*$variable_x+2" />
</xsl:template>

Il suffit alors de l'appeler en lui passant diverses valeurs pour le paramètre variable_x pour qu'il évalue cette expression. Ce comportement se rapproche de celui d'une fonction dans un langage de programmation. Par exemple...

<xsl:call-template name="polynome">
  <xsl:with-param name="variable_x" select="3.4" />
</xsl:call-template>

... permet d'afficher le résultat de 2*3.4^2-5*3.4+2. On remarquera que :

  1. la soustraction d'un nombre se fait par addition du nombre (négatif) opposé ;

  2. la division se fait non par le caractère /, mais par l'opérateur div.

Exercice 1. Utilisation d'éléments XSL

Énoncé
Correction

>Retour à la TdM

IV. Conception modulaire des feuilles de style

1. Introduction

Les feuilles de style que nous avons écrites jusqu'à présent conviennent à de petits projets. Cependant, lorsqu'un développement doit être réalisé à plusieurs, ou lorsqu'il devient nécessaire de revenir après quelque temps sur du code déjà écrit, la possibilité de mettre au point des feuilles de style modulaires prend toute sa valeur. Deux étages successifs le permettent :

  1. Au sein d'une même feuille de style, la séparation du traitement de chaque nœud peut se faire en généralisant l'emploi des templates ;

  2. Il est possible de scinder une feuille de styles en plusieurs fichiers, inclus les uns dans les autres.

>Retour à la TdM

2. Utilisation des templates

a. Introduction

Les feuilles de style que nous avons écrites jusqu'à présent utilisaient l'élément xsl:for-each pour « inspecter » successivement tous les éléments renvoyés par une expression XPath. Lorsque le document XML initial ou le document de sortie deviennent un peu complexes, cette méthode aboutit à l'écriture d'une feuille de style consistant en de multiples boucles imbriquées. Une solution commode est alors de séparer les traitements pour chaque nœud du document initial grâce aux éléments xsl:template.

b. Exemple

Revenons à la deuxième feuille de style que nous avions écrite pour présenter la liste des bouteilles :

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
    <head>
      <title>Exemple de sortie HTML</title>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    </head>
    <body>
      <h1>Bouteille de marque <xsl:value-of select="bouteille/marque" /> </h1>
      <h2>Composition:</h2>
      <h3>Ions positifs</h3>
      <ul>
        <xsl:for-each select="bouteille/composition/ion_positif">
          <li> <xsl:value-of select="." /> </li>
        </xsl:for-each>
      </ul>
      <h3>Ions négatifs</h3>
      <ul>
        <xsl:for-each select="bouteille/composition/ion_negatif">
          <li> <xsl:value-of select="." /> </li>
        </xsl:for-each>
      </ul>
      <h3>Autres matériaux</h3>
      <ul>
        <xsl:for-each select="//autres_materiaux">
          <li> <xsl:value-of select="." /> </li>
        </xsl:for-each>
      </ul>
<h2>Lieu d'origine</h2>
      <p>Ville de <b> <xsl:value-of select="bouteille/source/ville" /> </b>, dans le département <b> <xsl:value-of select="bouteille/source/departement" /> </b> </p>
      <h2>Autres informations</h2>
      <ul>
        <li>Contenance: <xsl:value-of select="bouteille/contenance" /> </li>
        <li>pH: <xsl:value-of select="bouteille/ph" /> </li>
      </ul>
    </body>
  </html>
</xsl:template>
</xsl:stylesheet>

Modifions-la dans un premier temps afin qu'elle puisse s'adapter à un document XML listant plusieurs bouteilles :

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
    <head>
      <title>Exemple de sortie HTML</title>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    </head>
    <body>
<xsl:for-each select="//bouteille">
      <h1>Bouteille de marque <xsl:value-of select="bouteille/marque" /> </h1>
      <h2>Composition:</h2>
      <h3>Ions positifs</h3>
      <ul>
        <xsl:for-each select="bouteille/composition/ion_positif">
          <li> <xsl:value-of select="." /> </li>
        </xsl:for-each>
      </ul>
      <h3>Ions négatifs</h3>
      <ul>
        <xsl:for-each select="bouteille/composition/ion_negatif">
          <li> <xsl:value-of select="." /> </li>
        </xsl:for-each>
      </ul>
      <h3>Autres matériaux</h3>
      <ul>
        <xsl:for-each select="//autres_materiaux">
          <li> <xsl:value-of select="." /> </li>
        </xsl:for-each>
      </ul>
      <h2>Lieu d'origine</h2>
      <p>Ville de <b> <xsl:value-of select="bouteille/source/ville" /> </b>, dans le département <b> <xsl:value-of select="bouteille/source/departement" /> </b> </p>
      <h2>Autres informations</h2>
      <ul>
        <li>Contenance: <xsl:value-of select="bouteille/contenance" /> </li>
        <li>pH: <xsl:value-of select="bouteille/ph" /> </li>
      </ul>
</xsl:for-each>
    </body>
  </html>
</xsl:template>
</xsl:stylesheet>

Les imbrications de boucles xsl:for-each peuvent devenir lourdes à gérer. Il est plus facile de maintenir la structure suivante :

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="html4.01" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" />

<xsl:template match="/">
  <html>
    <head>
      <title>Exemple de sortie HTML</title>
    </head>
    <body>
      <xsl:apply-templates />
    </body>
  </html>
</xsl:template>

<xsl:template match="bouteille">
  <h1>Bouteille de marque <xsl:value-of select="marque" /> </h1>
  <h2>Composition:</h2>
  <h3>Ions positifs</h3>
  <ul>
    <xsl:for-each select="composition/ion_positif">
      <xsl:apply-templates select="." />
    </xsl:for-each>
  </ul>
  <h3>Ions négatifs</h3>
  <ul>
    <xsl:for-each select="composition/ion_negatif">
      <xsl:apply-templates select="." />
    </xsl:for-each>
  </ul>
  <h3>Autres matériaux</h3>
  <ul>
    <xsl:for-each select="autres_materiaux">
      <xsl:apply-templates select="." />
    </xsl:for-each>
  </ul>
  <h2>Lieu d'origine</h2>
  <p>Ville de <b> <xsl:value-of select="source/ville" /> </b>, dans le département <b> <xsl:value-of select="source/departement" /> </b> </p>
  <h2>Autres informations</h2>
  <ul>
    <li>Contenance: <xsl:value-of select="contenance" /> </li>
    <li>pH: <xsl:value-of select="ph" /> </li>
  </ul>
</xsl:template>

<xsl:template match="ion_positif">
  <li> <xsl:value-of select="." /> </li>
</xsl:template>

<xsl:template match="ion_negatif">
  <li> <xsl:value-of select="." /> </li>
</xsl:template>

<xsl:template match="autres_materiaux">
  <li> <xsl:value-of select="." /> </li>
</xsl:template>

</xsl:stylesheet>

Le gain n'est pas très appréciable ici, mais si vous jetez un œil à la feuille de style qui figure en lien en bas de cette page, vous verrez un exemple d'utilisation plus complexe... et plus utile.

>Retour à la TdM

3. Inclusions de feuilles de style

Il est parfois nécessaire de scinder une feuille de style en plusieurs fichiers différents :

Pour cela, il suffit de spécifier dans la feuille de style « maîtresse » un appel à une feuille de style autre, soit par l'élément xsl:include soit par l'élément xsl:import. Par exemple...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:include href="feuille_incluse.xsl" />
</xsl:stylesheet>

Les modèles et variables définis dans la feuille de style ainsi incluse sont directement incorporés à la feuille de style appelante. Quand on utilise xsl:import, s'il y a conflit entre une déclaration de template dans la feuille appelante et la feuille appelée, c'est la première qui est prioritaire. La syntaxe est la même :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="feuille_incluse.xsl" />
</xsl:stylesheet>

>Retour à la TdM

Historique de ce document

Bibliographie

De l'auteur (G. Chagnon)

Conditions d'utilisation et licence

Creative Commons License
Cette création est mise à disposition par Gilles Chagnon sous un contrat Creative Commons.

Retour au menu