Chapitre 6 : Langage de transformation XSLT

6. Utiliser ou générer plusieurs documents

Plan de la section

  1. Différents documents source
  2. Génération de plusieurs documents

6.1. Différents documents source

Tout ce qui a été présenté jusqu'à maintenant permet de créer des programmes XSLT qui s'appliquent à un document source et qui produisent un document résultat. Or il est fréquent que des données soient réparties dans différents documents, et qu'on ait besoin d'utiliser ces différentes sources pour produire le document résultat. Pour être en mesure de s'exécuter, le programme XSLT doit être lié à un document (à transformer), que nous appellerons document maître, mais il peut accéder à autant d'autres documents (documents annexes) qu'il est nécessaire en utilisant la fonction document qui permet d'accéder au document dont l'URL est passé en paramètre.

document("URL du document")chemin dans le document

Nous donnons en exemple deux petits documents XML (ouvrages.xml et personnes.xml) et un programme XSLT (ouvrages.xsl). Celui-ci transforme le premier document (ouvrages.xml) et accède au second (personnes.xml) pour construire le document résultat.

<?xml version="1.0" encoding="UTF-8"?>
<!-- ouvrages.xml : document maître -->
<liste_ouvrages>
   <ouvrage>
     <titre>Relativité</titre>
     <auteur>p01</auteur>
   </ouvrage>
   <ouvrage>
     <titre>Gravitation</titre>
     <auteur>p02</auteur>
   </ouvrage>
   <ouvrage>
     <titre>Effet photoélectrique</titre>
     <auteur>p01</auteur>
   </ouvrage>
</liste_ouvrages>

ouvrages.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- personnes.xml : document annexe -->
<liste_personnes>
  <personne id="p01">
    <nom>Einstein</nom>
    <prenom>Albert</prenom>
  </personne>
  <personne id="p02">
    <nom>Newton</nom>
    <prenom>Isaac</prenom>
  </personne>
</liste_personnes>

personnes.xml
 
<?xml version="1.0" encoding="UTF-8"?>
<!-- ouvrages.xsl -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:template match="/">
     <html>
        <head></head>
        <body>
          <ol>
            <xsl:apply-templates select="//ouvrage"/>
          </ol>
        </body>
     </html>
   </xsl:template>
     
   <xsl:template match="ouvrage">
     <xsl:variable name="aut" select="auteur"/>
     <li>
       <xsl:value-of select="titre"/>
       <text> : </text>
       <xsl:value-of select="document('personnes.xml')//personne[@id=$aut]"/>
     </li>
   </xsl:template>
</xsl:stylesheet>

ouvrages.xsl
Résultat de la transformation dans le navigateur : ouvrages_xsl.xml

L'accès par la fonction document constitue le préfixe du chemin d'accès à l'élément voulu. Le prédicat permet de sélectionner la bonne personne grâce à l'identifiant. L'opération qui est réalisée sur ce petit exemple n'est autre qu'une jointure.

L'exemple ne fait appel qu'à un seul document annexe, mais on peut en utiliser autant qu'il est nécessaire. Cela a bien sûr une conséquence sur temps d'exécution de la transformation.

6.2. Génération de plusieurs documents

Un autre problème est celui de produire plusieurs documents avec un seul programme XSLT. Ceci n'est possible qu'avec la version 2.0 du langage, et donc les outils qui l'implémentent. Le contenu de chaque document à générer doit être écrit à l'intérieur de l'élément XSLT suivant. L'attribut format est facultatif. S'il est présent, il faut que sa valeur soit définie par l'attribut name d'une instruction xsl:output (voir l'exemple ci-dessous).

<xsl:result-document href="nom du document à générer" format="le format" >
   <!-- code du document à générer -->
</xsl:result-document>

Voici l'exemple d'un document bestiaire.xml qui contient le descriptif de plusieurs animaux.

<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="pages_animal.xsl"?>
  <bestiaire>
    <!-- baleine.htm -->
    <animal>
      <nom>baleine</nom>
      <image largeur="100" hauteur="100" position="à droite">baleine.jpg</image>
      <gram>nom féminin</gram>
      <etym>latin : balaena</etym>
      <desc> Mammifère marin, le plus grand des animaux. (Long. max. 33m ; poids 150 t environ ; ordre
     des cétacés.). La baleine se nourrit de plancton, retenu dans les fanons de corne pendant
     verticalement de sa mâchoire supérieure. Elle peut plonger une demi-heure, puis, en revenant la
     surface, elle expire de l'air saturé de vapeur d'eau. Chassée avec excès pour sa viande et pour
     sa graisse (30 t d'huile par animal), la vraie baleine est actuellement rare et confinée dans
     les mers polaires, où sa chasse, d'abord réglementée, a été interdite en 1987. </desc>
    </animal>
    <!-- chameau.htm -->
    <animal>
      <nom>chameau</nom>
      <image largeur="100" hauteur="100" position="à droite">chameau.jpg</image>
      <gram>nom masculin</gram>
      <etym>grec : kamlos</etym>
      <desc> Mammifère ruminant d'Asie centrale, deux bosses graisseuses sur le dos, adapté à la vie
     dans les régions arides où il sert de monture et d'animal de trait. (Famille des camélidés.) Le
     chameau blatère, pousse son cri. </desc>
    </animal>
    <!-- chat.htm -->
    <animal>
      <nom>chat</nom>
      <gram>nom masculin</gram>
      <etym></etym>
      <desc>Pas de descriptif</desc>
    </animal>
    <!-- lama.htm -->
    <animal>
      <nom>lama</nom>
      <image src="lama.jpg" largeur="100" hauteur="100" position="à droite">lama.jpg</image>
      <gram>nom masculin</gram>
      <etym>mot espagnol, du quechua</etym>
      <desc> Mammifère ruminant de la cordillère des Andes, dont il existe deux races sauvages (guanaco
     et vigogne) et deux races domestiques (alpaga et lama proprement dit) élevées pour leur chair et
     leur laine et utilisées comme bêtes de somme. (Famille des camélidés.) </desc>
    </animal>
    <!-- pie.htm -->
    <animal>
      <nom>pie</nom>
      <image largeur="100" hauteur="100" position="à droite">pie.jpg</image>
      <gram>nom féminin</gram>
      <etym>latin : pica</etym>
      <desc> Passereau plumage noir bleuté et blanc et longue queue, commun en France. La pie jacasse,
     jase, pousse son cri. </desc>
    </animal>
    <!-- crocodile.htm -->
    <animal>
      <nom>crocodile</nom>
      <image largeur="100" hauteur="100" position="à droite">crocodile.jpg</image>
      <gram> nom masculin</gram>
      <etym>latin : crocodilus</etym>
      <desc> Grand reptile fortes mâchoires, qui vit dans les fleuves et les lacs des régions chaudes.
     (Ordre des crocodiliens). Le crocodile vagit, pousse son cri. Le crocodile d'Amérique
     s'appelle l'alligator. </desc>
    </animal>
    <!-- condor.htm -->
    <animal>
      <nom>condor</nom>
      <image largeur="100" hauteur="100" position="à droite">condor.jpg</image>
      <gram>nom masculin</gram>
      <etym>mot espagnol, du quechua</etym>
      <desc> Grand vautour des Andes. </desc>
    </animal>
  </bestiaire>
 
bestaire.xml

Le programme XSLT ci-dessous génére autant de pages HTML qu'il y a d'animaux dans le document plus une page principale qui pointe sur chacune des pages d'animaux. La règle principale génére le code de la page principale puis lance une règle sur chaque animal. La règle animal crée la page de chaque animal à l'intérieur de l'élément xsl:result-document. Le nom du fichier qui contient chaque page est créé à partir du nom de l'animal (accolades pour extraire la valeur de l'élément nom). Des liens qui utilisent les noms de fichiers créés sont mis en place de la page principale vers les pages des animaux.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="html" encoding="UTF-8"/>
  <xsl:output method="html" encoding="UTF-8" name="html"/>
  <xsl:template match="/">
    <html>
      <body>
        <h3>Bestiaire</h3>
        <ul>
          <xsl:for-each select="bestiaire/animal ">
            <li><a href="{nom}.htm"><xsl:value-of select="nom"/></a></li>
          </xsl:for-each>
        </ul>   
        <xsl:apply-templates select="bestiaire/animal"/>
      </body>
    </html>   
  </xsl:template>
   
  <xsl:template match="animal">
    <xsl:result-document format="html" encoding="UTF-8" href="{nom}.htm" >
      <html>
        <body>
          <h3><xsl:value-of select="./nom"/></h3>
          <xsl:if test="image">   
            <xsl:element name="img">
              <xsl:attribute name="align">left</xsl:attribute>
              <xsl:attribute name="width">
                <xsl:value-of select="./image/@largeur"/>
              </xsl:attribute>
              <xsl:attribute name="height">
                <xsl:value-of select="./image/@hauteur"/>
              </xsl:attribute>
              <xsl:attribute name="src">
                <xsl:value-of select="./image"/>
              </xsl:attribute>
            </xsl:element>
          </xsl:if>
          <xsl:value-of select="desc"/>
        </body>
      </html>
    </xsl:result-document>
  </xsl:template>    
</xsl:stylesheet>   
  
pages_animal.xsl

Ci-dessous le code de la page principale qui a été générée, suivi du code de l'une des page animal. Contrairement aux autres exemples il n'est pas possible de faire exécuter la transformation par le navigateur puisqu'elle conduit à plusieurs pages HTML. Le lecteur devra donc exécuter lui-même la transformation avec l'un des outils qui implémentent le langage XSLT version 2.0 (voir section suivante). Cependant les fichiers résultant de la transformation sont en ligne et peuvent être obtenus en activant le lien sur bestiaire.htm.

<html>
  <body>
    <h3>Bestiaire</h3>
    <ul>
      <li><a href="baleine.htm">baleine</a></li>
      <li><a href="chameau.htm">chameau</a></li>
      <li><a href="chat.htm">chat</a></li>
      <li><a href="lama.htm">lama</a></li>
      <li><a href="pie.htm">pie</a></li>
      <li><a href="crocodile.htm">crocodile</a></li>
      <li><a href="condor.htm">condor</a></li>
    </ul>
  </body>
</html>

bestiaire.htm
<html>
   <body>
     <h3>baleine</h3>
     <img align="left" width="100" height="100" src="baleine.jpg">
     Mammifère marin, le plus grand des animaux. (Long. max. 33m ; poids 150 t environ ; ordre
     des cétacés.). La baleine se nourrit de plancton, retenu dans les fanons de corne pendant
     verticalement de sa mâchoire supérieure. Elle peut plonger une demi-heure, puis, en revenant la
     surface, elle expire de l'air saturé de vapeur d'eau. Chassée avec excès pour sa viande et pour
     sa graisse (30 t d'huile par animal), la vraie baleine est actuellement rare et confinée dans
     les mers polaires, où sa chasse, d'abord réglementée, a été interdite en 1987. 
   </body>
</html>