XSLT modulaire

XSLT modulaire #

Modularité avec les éléments « xsl:apply-templates » #

Cette section explique comment utiliser l’élément xsl:apply-templates pour rendre les feuilles de style XSLT plus modulaires et réutilisables, en évitant la répétition de code.

Notre fichier « xslt.xml » se complexifie et devient plus difficile à comprendre. Tout est dans un seul modèle, le modèle facture. Pour simuler un problème probable, imaginons que notre XML est plus complexe et prend la forme :

<?xml version="1.0" encoding="ISO-8859-1" ?>
    <?xml-stylesheet href="xslt.xml" type="application/xml"?>
    <facture>
     <montant>10.10</montant>
    <recipiendaire>
        <personne>
            <sexe>M</sexe>
            <nom>Rochond</nom>
            <prenom>Jean</prenom>
        </personne>
    </recipiendaire>
    <commercant>
        <personne>
            <sexe>F</sexe>
            <nom>Ladouce</nom>
            <prenom>Jeanne</prenom>
        </personne>
     </commercant>
     <raison>Achat d'ordinateur</raison>
     </facture>

Dans ce nouveau document XML, se trouvent deux éléments « personne ». Il serait bête, dans le document XSLT, de répéter le travail chaque fois qu’on veut afficher un élément « personne ». Regardons ce que cela pourrait donner en pratique :

<?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="facture">
    <html>
    <head>
    <title>Facture de <xsl:value-of select="personne" /></title>
    </head>
    <body>
     <p>Ceci est une facture pour 
     <xsl:value-of select="recipiendaire/personne/prenom" />
     <xsl:text> </xsl:text>
     <xsl:value-of select="recipiendaire/personne/nom" /> 
     de <xsl:value-of select="montant" />$ pour:
     <xsl:value-of select="raison" />.</p>
     <p>Votre commerçant: 
     <xsl:value-of select="commercant/personne/prenom" />
     <xsl:text> </xsl:text>
     <xsl:value-of select="commercant/personne/nom" /> </p>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>

Observez comment on répète le texte suivant à deux reprises :

<xsl:value-of select="recipiendaire/personne/prenom" />
           <xsl:text> </xsl:text>
    <xsl:value-of select="recipiendaire/personne/nom" />

Voici une autre solution, plus élégante, qui donne le même résultat :

<?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- d'abord un modèle pour les éléments facture -->
    <xsl:template match="facture">
    <html>
    <head>
    <title>Facture de <xsl:value-of select="recipiendaire/personne" /></title>
    </head>
    <body>
     <p>Ceci est une facture pour 
     <xsl:apply-templates select="recipiendaire" /> 
     de <xsl:value-of select="montant" />$ pour: 
     <xsl:value-of select="raison" />.</p>
     <p>Votre commerçant: <xsl:apply-templates select="commercant" /> </p>
    </body>
    </html>
    </xsl:template>
    <!-- le modèle pour les éléments facture 
    utilise un modèle pour les éléments personne -->
    <xsl:template match="personne">
           <xsl:value-of select="prenom" />
           <xsl:text> </xsl:text>
           <xsl:value-of select="nom" />
    </xsl:template>
    </xsl:stylesheet>

Quelques éléments « xsl:value-of » ont été remplacés par des éléments « xsl:apply-templates ». Un élément « xsl:apply-templates » prend le contenu et, au lieu d’insérer le contenu textuel comme le fait « xsl:value-of » à l’endroit prévu, il insère plutôt le résultat obtenu par l’application de modèles (éléments « xsl:template »). Ainsi, dans l’exemple que nous venons de voir, chaque fois que le processeur XSLT rencontre l’instruction « <xsl:apply-templates select=“recipiendaire” /> », il prend l’élément « recipiendaire » et essaie d’appliquer ses modèles. Comme il n’a pas de modèle pour les éléments « recipiendaire », il explore le contenu de l’élément et y trouve immédiatement un élément « personne ». Puisqu’il dispose d’un modèle pour ce type d’élément, il va l’appliquer. Par ailleurs, comme les éléments « recipiendaire » et « commercant » ne contiennent qu’un élément « personne », c’est donc le modèle défini pour les éléments « personne » qui s’appliquera dans les deux cas.

Normalement, les éléments « xsl:apply-templates » sont utilisés au sein des éléments « xsl:template ». On peut aussi les utiliser au sein d’autres éléments que nous discuterons prochainement, « xsl:param » et « xsl:variable ».

Notre fichier « xslt.xml » est maintenant plus modulaire, parce qu’il contient deux modèles (éléments « xsl:template »).

En résumé, il est souvent préférable d’utiliser un élément « xsl:apply-templates » qu’un élément « xsl:value-of » quand la complexité du modèle augmente; ceci permet d’assurer la modularité et de garder la simplicité du document XSLT.

Par défaut, l’instruction apply-templates traite les nœuds dans l’ordre où ils se présentent dans le document original. On peut forcer le XSLT à trier les éléments avant de le traiter avec l’instruction xsl:sort. Dans notre exemple, on peut remplacer l’élément <xsl:apply-templates select=“recipiendaire” /> par cet élément si on veut que les individus soient triés par leur nom de famille.

<xsl:apply-templates select="étudiant" >
   <xsl:sort select="personne/nom" order="ascending" data-type="text" />
   </xsl:apply-templates>

Si on souhaite un tri sur la valeur numérique d’une expression, on remplacera data-type=“text” par data-type=“number”.

On peut aussi importer un autre fichier XSLT avec l’instruction xsl:import. Celle-ci doit apparaître au tout début du fichier XSLT comme premier sous-élément de l’élément xsl:stylesheet comme dans cet exemple :

<?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:import href="mesregles.xsl"/>
    <xsl:template match="facture">
    <html>
    <head>
    <title>Facture de <xsl:value-of select="personne" /></title>
    </head>
    </xsl:template>
    </xsl:stylesheet>

En cas de conflit entre les règles de fichier XSLT principal et celles du fichier importé, les règles du fichier XSLT principal l’emporte.