Text only | Skip links
Skip links||IT Services, University of Oxford

1. XSLT, qu’est-ce que c’est ?

XSLT signifie Extensible Stylesheet Language Transformations.

Langage informatique dont les spécifications ont été publiées par le W3C en novembre 1999, en même temps que celles relatives au langage XPath

XSLT 1.0 : <http://www.w3.org/TR/xslt> ; une traduction française (sans valeur normative) : <http://xmlfr.org/w3c/TR/xslt/>

2. Le cahier des charges initial du langage

Voir XSL Requirements Summary : W3C Working Draft 11-May-1998 : (écrit par Norman Walsh). Il fallait un langage pour transformer des documents XML, ayant les qualités suivantes :
  • écrit en XML
  • capable de générer autre chose à partir d’un document source
  • permettant de réutiliser certaines instructions (comme des macros)
  • pas de sens dans l’écriture
  • extensible (ouvert sur d’autres langages)
  • ...

Donc un langage déclaratif basé sur des instructions (on dit des règles) non ordonnées, comme CSS, mais beaucoup plus puissant. On y spécifie une sortie à produire à partir d’un segment du fichier XML, si ce segment existe et répond à certains critères.

Depuis 1999 (XSLT 1), a été conçu et spécifiée une autre version du langage, XSLT 2 (2007 ; comme pour XPath 2).

3. Cas d’utilisation

Dès que du XML existe et demande à être transformé, XSLT est la technologie majeure. Deux situations :
  • conversion d’informations structurées en XML conformément à un modèle A en informations structurées en XML conformément à un modèle B (ex. EAD ou TEI vers Dublin Core, format propriétaire vers TEI)... Le but est alors de permettre l’échange d’informations entre applications utilisant des modèles de données différents (assurer l’interopérabilité)
  • publication de documents XML, i.e. production de divers formats de sortie. Cas d’utilisation principal : génération de pages Web, en (X)HTML ; peut aussi être génération de fichiers texte, etc. Cf. le langage XSL-FO, qui est de la même famille, et qui permet de générer du PDF à partir de documents XML.

4. Scénarios d’implémentation

En gros, deux manières de faire :
  • utiliser XSLT statiquement, c’est-à-dire une fois pour toutes, par ex. pour passer d’un modèle documentaire à un autre et laisser de côté les documents conformes au premier modèle, ou pour produire des pages HTML que l’on va simplement déposer sur un serveur pour les rendre consultables. Un exemple : ce site Web <http://www.enc.sorbonne.fr/tmp/pierre-christofle/index.html> ; ou encore, le TP qu’on va faire tout à l’heure.
  • utiliser XSLT dans un environnement Web dynamique, pour faire dialoguer autant que nécessaire des applications, ou pour générer sur demande de l’utilisateur des pages Web. Exemples : échange d’informations entre un entrepôt et un moissonneur OAI-PMH ; ou encore le présent site Web, le site Web des lettres de Vincent Van Gogh, le site Web des chartes de Saint-Denis, etc. Ou, beaucoup plus simple, votre navigateur Web : s’il n’est pas trop ancien, il est capable de transformer du XML (TEI) en une page HTML - certes peu sexy, mais bon.

5. Dans tous les cas...

Pour que ça marche, il faut au moins :
  • un (ou plusieurs) document(s) XML à transformer, ils doivent être bien formés (et en principe, valides s’ils sont conformes à un modèle)
  • un programme XSLT
  • un processeur XSLT (un logiciel qui sache lire le programme XSLT et le document XML et qui opère la transformation demandée en suivant les instructions du programme)

Il y a de nombreux processeurs XSLT, notamment sous la forme de logiciels libres. Citons Xalan, Saxon, libxslt. On verra que oXygen, le logiciel utilisé pendant les TP, embarque certains processeurs XSLT.

6. Comment ça marche ?

En gros, le processus peut être décrit de la manière suivante :
  • parsing du document source, et création en mémoire d’une représentation arborescente de celui-ci ;
  • recherche, dans le programme XSLT, d’une règle s’appliquant à la racine du document XML, exécution de l’instruction et création d’un morceau de l’arbre résultat ;
  • sauf si la règle retenue commande de sélectionner un autre nœud, retour à l’arbre source et parcours de cet arbre, du haut vers le bas, de gauche à droite, en cherchant à chaque fois une règle dédiée ; s’il y a plusieurs règles applicables pour un même nœud, certaines règles de priorité s’appliquent ; s’il n’y a pas de règle applicable pour un nœud à traiter, alors le processeur applique les instructions par défaut (voir ci-après)
  • à la fin du processus, sérialisation de l’arbre résultat pour produire en sortie un flux textuel, selon les instructions spécifiées en tête de programme (en HTML, en XML, par ex.)

7. Le modèle abstrait utilisé : le document XML vu comme un arbre

L’arbre peut être représenté la racine en haut, comme un arbre généalogique - mais avec un seul et unique ancêtre :-)

Dans un arbre XML on distingue des nœuds, de 7 types :
  • nœud racine (ou nœud Document) ; attention ce n’est pas un élément, ne pas le confondre avec l’élément racine !
  • les éléments (Element) (ils ont un nom)
  • les attributs (Attribute) (ont un nom et une valeur)
  • le texte ou les valeurs textuelles et sections littérales (Text) (ont une valeur)
  • les commentaires (Comment) (ont pour valeur le texte du commentaire)
  • les instructions de traitement (ProcessingInstruction) (ont pour nom le programme cible, pour valeur des arguments)
  • les espaces de noms (Namespace) (désignés par un préfixe, ont pour valeur une uri)

8. Sélection des nœuds dans un arbre : le langage XPath

XSLT utilise beaucoup le langage XPath, en fait chaque fois qu’il s’agit de définir un motif (un nœud ou un ensemble de nœuds XML répondant à certains critères) auquel appliquer une règle de transformation, ou encore chaque fois qu’il s’agit de traiter un nœud/ensemble de nœuds.

XPath est un langage d’exploration et de sélection de nœuds XML, qui peut être très utile même hors du contexte XSLT.

9. Utilisation de XPath dans un programme XSLT : exemples

Deux cas :
  • Sélection d’un motif :
    <xsl:template match="tei:div[@type='transcription']">
    <!-- le motif est une expression XPath qui désigne tous les nœuds éléments dont le nom est div, tels que l’attribut type a la valeur transcription -->
     <xhtml:div class="transcription">
      <xsl:apply-templates/>
    <!-- l’instruction de transformation consiste à produire, si on rencontre un nœud répondant à ce motif, un élément (XHTML) div, et dans cet élément, à traiter les nœuds fils du nœud sélectionné -->
     </xhtml:div>
    </xsl:template>
  • Manipulation de nœuds à l’intérieur d’une règle
    <xsl:template match="tei:persName">
     <xhtml:span class="persName">
    <!-- dans l’élément XHTML span que la règle commande de générer pour chaque élément persName, on concatène la valeur textuelle du nœud élément forename, un blanc, et la valeur textuelle du nœud élément surname -->
    <!-- concat() est une fonction du langage XPath; de plus ici "child::tei:forename" est une expression XPath -->
      <xsl:value-of
        select="concat(child::tei:forename, ' ', child::tei:surname)"/>

     </xhtml:span>
    </xsl:template>

10. Composants d’une expression XPath

En quelques mots, une expression XPath décompose en étapes successives le processus de sélection d’un nœud :

Le slash est utilisé dans l’expression pour séparer les étapes.

Une étape de sélection combine un axe (sens de parcours des nœuds), un filtre (le type de nœuds retenu), et facultativement un prédicat (propriété(s) que le nœud doit satisfaire). Une étape commence par la désignation de l’axe, puis on trouve la chaîne "::", puis les filtres (tests sur un nœud) et prédicats. Une étape est donc écrite conformément au formalisme suivant :

11. Les axes XPath

Il y a treize axes :
self
le nœud contexte lui-même
child
les nœuds enfants du nœud contexte
parent
le nœud père du nœud contexte
descendant
les nœuds descendants du nœud contexte
descendant-or-self
les nœuds descendants du nœud contexte, et le nœud contexte
ancestor
tous les ancêtres du nœud contexte
ancestor-or-self
les nœuds ancêtres du nœud contexte, et le nœud contexte
following
les nœuds suivant le nœud contexte dans l’ordre de parcours du document, à l’exception des nœuds descendant du nœud contexte
following-sibling
tous les frères droits du nœud contexte
preceding
les nœuds précédant le nœud contexte dans l’ordre de parcours du document, à l’exception des ancêtres du nœud contexte
preceding-sibling
tous les frères gauches du nœud contexte
attribute
les attributs du nœud contexte
namespace
les espaces de noms

12. Axes : notations complètes ou abrégées

L’axe child est l’axe par défaut. Donc
<xsl:value-of select="tei:forename"/>
est équivalent à :
<xsl:value-of select="child::tei:forename"/>
Autre conséquence : s’il n’y a pas de slash au début d’une expression XPath, cela signifie qu’on part du nœud préalablement sélectionné.

Par contre, attention !! l’expression "/" seule désigne le nœud document.

L’étape par défaut est "descendant-or-self::node()" ; donc l’expression "//" est équivalente à "/descendant-or-self::node()/"

L’expression "." est équivalente à "self::node()" (le nœud sur lequel on se situe lui-même)

l’expression ".." est équivalente à "parent::node()" (le nœud parent du nœud dont on part)

13. Filtres XPath

Permettent de sélectionner un type de nœud dans l’ensemble de nœuds défini par l’axe

Exemples

<!-- en partant du nœud document, on traite tous les nœuds de type élément qui sont fils de teiHeader --><xsl:apply-templates select="/TEI:tei/tei:teiHeader/child::*"/>
<!-- on traite tous les attributs de l’élément courant -->
<xsl:apply-templates select="attribute::*"/>
<!-- ou encore, équivalent : -->
<xsl:apply-templates select="@*"/>
<!-- on traite tous les nœuds sauf les attributs -->
<xsl:apply-templates select="node()"/>
<!-- filtrage par nom d’élément -->
<xsl:apply-templates select="child::tei:fileDesc"/>
<!-- filtrage par nom d’attribut -->
<xsl:value-of select="child::tei:ref/@target"/>

14. Prédicats XPath

S’écrivent entre crochets, ce sont des expressions booléennes : si le prédicat est vrai pour un nœud donné, le nœud est sélectionné.

Peuvent inclure des fonctions telles que le calcul de la position, un traitement de chaîne etc.

Quelques-unes des fonctions parmi les plus utilisées dans le contexte d’un programme XSLT :
  • fonctions sur des ensembles de nœuds : position(), last(), document()
  • booléennes : false(), true(), not(arg)
  • numériques : number(arg), count(node-set), sum(node-set)...
  • de manipulation de chaînes : starts-with(), string-length(), substring(), substring-before(), substring-after(), translate(), concat(), contains()

Les opérateurs = , !=, <, >, <= et >= peuvent être utilisés pour les types numériques, chaînes et booléens. On dispose aussi des connecteurs logiques and et or.

15. Structure d’un programme XSLT

Un programme XSLT est un fichier XML.

L’élément racine est <xsl:stylesheet>, qui a deux attributs obligatoires, version (pour spécifier quelle version du langage XSLT on utilise) et xmlns (pour définir l’espace de noms XSL).

Un des éléments de haut niveau dans un programme XSLT est <xsl:output>, qui spécifie quel est le format de sortie.

Exemple
<xsl:stylesheet version="1.0exclude-result-prefixes="tei">
<!-- ci-dessus les 3 derniers attributs concernent l’espace de noms du document à produire et l’espace de noms du document XML à transformer -->
<!-- xsl:output : ici, pour demander la sortie d’un fichier XML conforme à une des DTD HTML, soit un fichier XHTML -->
 <xsl:output
   indent="yes"
   method="xml"
   encoding="UTF-8"
   doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
   doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<!-- d’autres éléments XSLT -->
</xsl:stylesheet>

16. XSLT : une affaire de règles

Les instructions de transformation XSLT sont englobées dans des éléments <xsl:template> (des règles). Chaque règle <xsl:template> a obligatoirement, soit un attribut match (cas le plus fréquent : c’est la valeur de cet attribut qui définit le motif ou pattern auquel un nœud XML doit répondre pour que la transformation soit réalisée), soit un attribut name (cas de la règle nommée : elle peut être réutilisée, comme une macro, puisqu’on peut la désigner par ce nom).

De manière générale, l’ordre d’écriture des règles importe peu, puisque le processeur parcourt l’arbre XML et cherche à quel motif le nœud trouvé correspond.

Attention de ne pas écrire plusieurs règles s’appliquant au même nœud... Certains processeurs vont signaler une erreur, voire s’arrêter.

17. Corps des règles

Dans une règle <xsl:template>, on trouve les instructions à appliquer aux nœuds conformes au motif indiqué dans match.

Ces instructions sont exprimées à l’aide d’éléments XML définis dans le langage XSLT. Impossible de les citer tous ici. On a déjà vu deux des plus couramment utilisés, <xsl:value-of> et <xsl:apply:templates>.

Mentionnons :
  • <xsl:element> : génération d’un élément
  • <xsl:attribute> : génération d’un attribut
  • <xsl:text> : génération d’une chaîne de caractères
  • <xsl:if> : test sur une condition, et exécution des instructions si le test est vérifié
  • <xsl:for-each> : exécution d’instructions en bouclant sur chacun des nœuds désigné par l’attribut select
  • <xsl:choose> : exécution d’une série de tests, pour le premier vérifié exécution de l’instruction qui lui est associée
  • <xsl:copy> : copie du nœud courant
  • <xsl:sort> : tri de l’ensemble de nœuds sélectionnés par <xsl:for-each> ou <xsl:apply-templates>
  • <xsl:variable> : déclaration d’une variable
  • <xsl:param> : déclaration de paramètre
  • ...

18. Règles modèles internes (par défaut)

Si le processeur, en parcourant le document XML selon le chemin indiqué, trouve un nœud qui ne correspond à aucun motif ? eh bien il fait quand même quelque chose ! il applique des instructions de transformation par défaut :
  • pour un nœud élément ou pour le nœud document : il passe aux nœuds enfants
  • pour un nœud texte : il sort la valeur textuelle
  • pour un nœud attribut : idem

Si on oublie cela, on peut avoir des surprises, ou encore s’arracher les cheveux ! et donc...

19. Règle vide

... et donc on a toujours besoin d’écrire ce genre de choses :
<xsl:template match="tei:encodingDesc"/>
parce que cela permet de ne pas traiter du tout le nœud désigné par le motif, ni son contenu quel qu’il soit.

20. Et si on veut juste modifier un peu son document XML ?

On peut écrire une XSLT qui va essentiellement tout copier à l’identique, sauf pour certains nœuds.


<!-- la première instruction traite le nœud document et commande simplement de parcourir les nœuds fils en profondeur --><xsl:template match="/">
 <xsl:apply-templates/>
</xsl:template>
<!-- la 2e traite tous les nœuds (avec node(), sauf les nœuds attributs) et tous les nœuds attr (avec @*). Elle les copie simplement, puis passe au traitement des nœuds fils ; elle permet donc de tout copier récursivement -->
<xsl:template match="node() | @*">
 <xsl:copy>
  <xsl:apply-templates select="node() | @*"/>
 </xsl:copy>
</xsl:template>
<!-- La 3e règle se contente de dire qu’on ne veut rien faire avec persName, par conséquent si la XSLT se termine ici, tout le document XML/TEI sera copié à l’identique, sauf les éléments persName, qui seront carrément supprimés -->
<xsl:template match="tei:persName"/>

21. Aller plus loin...

Beaucoup, beaucoup d’autres choses à dire. C’est un langage à part entière, il faut du temps pour en avoir une idée générale, et du temps pour bien le maîtriser.

Les TP vont permettre de s’amuser un peu avec une XSLT toute prête.

22. Bibliographie très sommaire

  • Comprendre XSLT [Texte imprimé] / Bernd Amann et Philippe Rigaux. - Cambridge ; Cologne ; Paris [etc] : O’Reilly, 2002 (05-Gap : Impr. Louis-Jean). - IX-517 p. : ill., couv. ill. ; 24 cm. - Index. - ISBN 2-84177-148-2.
  • XSLT [Texte imprimé] : la référence du programmeur / Michael Kay ; trad. de l’anglais, 2e éd., par Dominique Poupon, Ingrid Pigueron, Henri-Daniel Mrozek... [et al.]. - Paris : Wrox press : Pearson education France : diff. CampusPress, 2001 (63-Marsat : Impr. la Source d’or). - XXVI-806 p. : ill., couv. ill. ; 23 cm. - Trad. de : XSLT programmer’s reference. -Index. Résumés.
  • Un tutoriel parmi beaucoup d’autres : <http://www.zvon.org/xxl/XSLTreference/Output/index.html>


Florence Clavaud (École nationale des chartes). Date: juin et septembre 2010
Copyright University of Oxford