X - Patterns de transformation
        Copie non conforme
                Motivation
                Copie conforme générique
                Copie presque conforme
        Détection d'un élément avec domaine nominal par défaut
                Motivation
                Solution
                Exemple
        Références croisées inter fichiers
                Motivation
                Réalisation
                        Instanciation du nom de l'artiste
                        Instanciation des Nos de plages
                        Instanciation des noms d'instruments
                        Programme complet
        Génération d'hyper liens
                Motivation
                Réalisation avec recherche par clé
                Réalisation avec recherche par expression XPath
        Regroupements
                Motivation
                Regroupements par valeur ou par position
                        Des pièces regroupées par surface habitable (regroupement par valeur d'attributs)
                        Les villes regroupées par pays (regroupement par valeur d'attributs)
                        Les instrumentistes regroupés par instruments (regroupement par valeur de nœuds texte)
                        Les villes trois par trois (regroupement positionnel)
                Regroupements hiérarchiques
                        Exemple générique
                        Reconstitution hiérarchique d'un texte
                        Exemple atypique
        Génération d'une feuille de style par une autre feuille de style
                Motivation
                Exemple
        Génération de pages HTML dynamiques
                Motivation
                Réalisation
        Génération de pages HTML dynamiques pour un portail
        Localisation d'une application
                Motivation
                Réalisation
        Construction dynamique de l'agencement d'un tableau HTML
                Version statique
                Version dynamique
                        Pattern
        Génération de documents multiples


Chapitre X - Patterns de transformation

Copie non conforme

Motivation

Copie conforme générique

<xsl:template match="*">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
La recopie d'un élément, c'est :
la copie de cet élément
    à laquelle on accroche :
        - la recopie du premier enfant
        - la recopie du deuxième,
        - ...
        - la recopie du dernier enfant,
        - ou rien s'il n'y a pas d'enfant.
La recopie d'un élément, c'est :
la copie de cet élément
    à laquelle on accroche :
        - la recopie des attributs s'il y en a,
        - la recopie des enfants s'il y en a.
la recopie d'un élément ou d'un attribut, c'est :
la copie de cet élément ou de cet attribut
    à laquelle on accroche :
        - la recopie des attributs s'il y en a,
        - la recopie des enfants s'il y en a.
<xsl:template match="child::*|attribute::*">
    <xsl:copy>
        <xsl:apply-templates select="attribute::*"/>
        <xsl:apply-templates select="child::*"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="child::node()|attribute::*">
    <xsl:copy>
        <xsl:apply-templates select="attribute::*"/>
        <xsl:apply-templates select="child::node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="child::node()|attribute::*">
    <xsl:copy>
        <xsl:apply-templates select="child::node() | attribute::*"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="child::node()|attribute::*" mode="copie">
    <xsl:copy>
        <xsl:apply-templates select="attribute::*" mode="copie"/>
        <xsl:apply-templates select="child::node()" mode="copie"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="child::node()|attribute::*" priority="-10">
    <xsl:copy>
        <xsl:apply-templates select="attribute::*" />
        <xsl:apply-templates select="child::node()" />
    </xsl:copy>
</xsl:template>

Copie presque conforme

doc.xml
<?xml version="1.0" encoding="UTF-16"?>
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-16"/>
      <title>Génération de la documentation avec Docbook</title>
      <link rel="stylesheet" href=".\docbook.css" type="text/css"/>
      <meta name="generator" content="DocBook XSL Stylesheets V0"/>
   </head>
   <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
      <div class="article"> <div class="titlepage">
            <div> <h1 class="title">
               <a name="d0e1"></a>Génération de la documentation avec Docbook
               </h1>
            </div>
         </div>
         <p>Toutes ces modifications se trouvent dans le fichier principal <tt xmlns="http://www.w3.org/TR/xhtml1/transitional" class="filename">C:\DocBook\RunDocBook\extensions\verbatim.java</tt>, qui a finalement l'allure suivante:

        <table xmlns="http://www.w3.org/TR/xhtml1/transitional" 
               border="1" bgcolor="#E0E0E0">
        <caption align="right" class="listingTitle">verbatim.java</caption>
        <tr><td>
            <pre class="programlisting">
// ici listing de programme Java</pre>
        </td></tr>
        </table>
        </p>
         <!-- ... suite du fichier sans importance ... -->
      </div>
   </body>
</html>
copie.xsl
<?xml version='1.0' encoding='ISO-8859-1' ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version='1.0'> 
    
    <xsl:output  method='xml' indent="yes" encoding='ISO-8859-1' />
    
    <xsl:template match="/">
        <html>
            <xsl:apply-templates/>
        </html>
    </xsl:template>
    
    <xsl:template match="/html/head">
        <head>
            <xsl:apply-templates/>
        </head>
    </xsl:template>
    
    <xsl:template match="/html/head/*">
    </xsl:template>
    
    <xsl:template match="/html/head/title" priority="2">
        <xsl:apply-templates select="." mode="copie"/>
    </xsl:template>
    
    <xsl:template match="body">
        <xsl:apply-templates select="." mode="copie"/>
    </xsl:template>
    
    <xsl:template match="child::node() | attribute::*" mode="copie">
        <xsl:copy>
            <xsl:apply-templates select="@*" mode="copie"/>
            <xsl:apply-templates select="node()" mode="copie" />
        </xsl:copy>
    </xsl:template> 
   
</xsl:stylesheet>

Détection d'un élément avec domaine nominal par défaut

Motivation

<xsl:template match="truc">
        ...
</xsl:template>
<xsl:template match="*[ local-name() = 'truc' ]">
        ...
</xsl:template>

Solution

<machin xmlns="http://www.machinchose.fr/bidule">
    <truc>
        ...
    </truc>
</machin>
<machin xmlns:xx="http://www.machinchose.fr/bidule">
    <xx:truc>
        ...
    </xx:truc>
</machin>
tout élément "truc" dont le préfixe est "xx"
tout élément "truc" dont le domaine nominal est
http://www.machinchose.fr/bidule
<?xml version='1.0'?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:xx="http://www.machinchose.fr/bidule"
                
    version='1.0'>
                
<!-- etc -->
<xsl:template match="xx:truc">
        ...
</xsl:template>
<machin xmlns="http://www.machinchose.fr/bidule">
    <truc>
        ...
    </truc>
</machin>

Exemple

doc.html
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-16"/>
      <title>Génération de la documentation avec Docbook</title>
      <link rel="stylesheet" href=".\docbook.css" type="text/css"/>
      <meta name="generator" content="DocBook XSL Stylesheets V0"/>
   </head>
   <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" 
         alink="#0000FF">
      <div class="article"> <div class="titlepage">
            <div> <h1 class="title">
               <a name="d0e1"></a>Génération de la documentation avec Docbook
               </h1>
            </div>
         </div>
         
         <div class="sect1"> <div class="titlepage">
               <div> <h2 class="title" style="clear: both">
                  <a name="d0e38"></a>1. Documentation avec docbook
                  </h2>
               </div>
            </div>
            
            <div class="sect2"> <div class="titlepage">
                  <div><h3 class="title">
                     <a name="d0e46">
                     </a>1.2. Description des principaux fichiers utiles
                     </h3>
                  </div>
               </div>
               
               <div class="sect3"> <div class="titlepage">
                     <div> <h4 class="title">
                        <a name="d0e231"></a>1.2.6. puratim.class
                        </h4>
                     </div>
                  </div>
         <p>Toutes ces modifications se trouvent dans le fichier principal 
         <tt xmlns="http://www.w3.org/TR/xhtml1/transitional" 
         class="filename">C:\DocBook\RunDocBook\extensions\puratim.java</tt>, 
             qui a finalement l'allure suivante:
        
<table xmlns="http://www.w3.org/TR/xhtml1/transitional" 
       border="1" bgcolor="#E0E0E0">
<caption align="right" class="listingTitle">puratim.java</caption>
     <tr>
        <td>
            <pre  class="programlisting">
import java.io.*;
public class puratim {
    public static void main( String arg[] ) {   
        try {
            FileInputStream fis = new FileInputStream( arg[0] );
            InputStreamReader isr = new InputStreamReader( fis, "UTF-16" );
            BufferedReader in = new BufferedReader( isr );
            ...
            line = in.readLine(); // la 2° ligne n'est pas recopiée 
                                  // (c'est la référence au graphe)
            
            for(;;){
                line = in.readLine();
                if ( line == null ) break;
                pw.println( line );
            }
            ...
        }
        ...
    }
}</pre>
</td>
</tr>
</table>
</p>

<p>A priori le service "Sécurité des réseaux" est au courant de ce problème, 
qui devrait donc être résolu dans les jours qui viennent. 
Lorsque ce sera le cas, on pourra supprimer ce fichier 
<tt xmlns="http://www.w3.org/TR/xhtml1/transitional" 
class="filename">puratim.class</tt>
</p>
               </div>
            </div>
         </div>
      </div>
   </body>
</html>
<?xml version='1.0'?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:dns="http://www.w3.org/TR/xhtml1/transitional"
                
    version='1.0'>
                
<!-- etc -->
<xsl:template match="dns:pre">
    <pre class="programlisting">
    <xsl:call-template name="replace_first_tabs_on_all_lines">
        <xsl:with-param name="codeSource" select="." />
    </xsl:call-template>
    </pre>
</xsl:template>
<pre 
    xmlns="" 
    xmlns:dns="http://www.w3.org/TR/xhtml1/transitional" 
    class="programlisting">
import java.io.*;
public class puratim {
    public static void main( String arg[] ) {
    ...
}</pre>
<xsl:template match="dns:pre">
    <dns:pre class="programlisting">
    <xsl:call-template name="replace_first_tabs_on_all_lines">
        <xsl:with-param name="codeSource" select="." />
    </xsl:call-template>
    </dns:pre>
</xsl:template>
<dns:pre 
    xmlns:dns="http://www.w3.org/TR/xhtml1/transitional" 
    class="programlisting">
import java.io.*;
public class puratim {
    public static void main( String arg[] ) {
    ...
}</dns:pre>
tabsToSpaces.xsl
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dns="http://www.w3.org/TR/xhtml1/transitional"
                version='1.0'> 
 
    
    <xsl:output  method='html' encoding='ISO-8859-1' />
    
    <xsl:template name="replace_first_tabs_on_all_lines">
        ...
    </xsl:template>
    
    
    <xsl:template match="/">
        <xsl:apply-templates mode="copie"/>
    </xsl:template>
    
    <xsl:template match="dns:pre" mode="copie">
        <xsl:comment>Dans pre[@class='programlisting]'</xsl:comment>
        <dns:pre class="programlisting">
        <xsl:call-template name="replace_first_tabs_on_all_lines">
            <xsl:with-param name="codeSource" select="." />
        </xsl:call-template>
        </dns:pre>
    </xsl:template>
    
    <xsl:template match="child::node() | attribute::*" mode="copie">
        <xsl:copy>
            <xsl:apply-templates select="@*" mode="copie"/>
            <xsl:apply-templates select="node()" mode="copie" />
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>
docSansTabs.html
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-16">
      <title>G&eacute;n&eacute;ration de la documentation avec Docbook</title>
      <link rel="stylesheet" href=".\docbook.css" type="text/css">
      <meta name="generator" content="DocBook XSL Stylesheets V0">
   </head>
   <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" 
         alink="#0000FF">
      <div class="article"> 
         <div class="titlepage">
            <div> 
               <h1 class="title">
               <a name="d0e1"></a>
               G&eacute;n&eacute;ration de la documentation avec Docbook
               </h1>
            </div>
         </div>
                 
         <div class="sect1"> 
            <div class="titlepage">
               <div> 
                  <h2 class="title" style="clear: both">
                  <a name="d0e38"></a>1. Documentation avec docbook
                  </h2>
               </div>
            </div>
                        
            <div class="sect2"> 
               <div class="titlepage">
                  <div>
                     <h3 class="title">
                     <a name="d0e46"></a>
                     1.2. Description des principaux fichiers utiles
                     </h3>
                  </div>
               </div>
                           
               <div class="sect3"> 
                  <div class="titlepage">
                     <div> 
                        <h4 class="title">
                        <a name="d0e231"></a>1.2.6. puratim.class
                        </h4>
                     </div>
                  </div>
<p>Toutes ces modifications se trouvent dans le fichier principal 
<tt xmlns="http://www.w3.org/TR/xhtml1/transitional"   
    class="filename">C:\DocBook\RunDocBook\extensions\puratim.java</tt>,
    qui a finalement l'allure suivante:
        
 <table xmlns="http://www.w3.org/TR/xhtml1/transitional" 
        border="1" bgcolor="#E0E0E0">
    <caption align="right" class="listingTitle">puratim.java</caption>
    <tr>
       <td>
<!--Dans pre[@class='programlisting]'-->
<dns:pre 
        xmlns:dns="http://www.w3.org/TR/xhtml1/transitional" 
        class="programlisting">
import java.io.*;
public class puratim {
 public static void main( String arg[] ) {   
     try {
         FileInputStream fis = new FileInputStream( arg[0] );
         InputStreamReader isr = new InputStreamReader( fis, "UTF-16" );
         BufferedReader in = new BufferedReader( isr );
         ...
         line = in.readLine(); // la 2&deg; ligne n'est pas recopi&eacute;e 
                               // (c'est la r&eacute;f&eacute;rence au graphe)
         for(;;){
             line = in.readLine();
             if ( line == null ) break;
             pw.println( line );
         }
         ...
     }
     ...
 }
}
</dns:pre>
       </td>
    </tr>
 </table>
</p>
<p>A priori le service "S&eacute;curit&eacute; des r&eacute;seaux" 
est au courant de ce probl&egrave;me, qui devrait donc &ecirc;tre 
r&eacute;solu dans les jours qui viennent. Lorsque ce sera le cas, 
on pourra supprimer ce fichier 
<tt xmlns="http://www.w3.org/TR/xhtml1/transitional" 
    class="filename">puratim.class</tt>
</p>
               </div>
            </div>
         </div>
      </div>
   </body>
</html>

Références croisées inter fichiers

Motivation

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

    <artistes>
        <artiste id="cplu" name="Christine Plubeau"/>
        <artiste id="nspt" name="Noëlle Spieth"/>
        <artiste id="eblq" name="Eric Bellocq"/>
        <artiste id="fmrt" name="Frédéric Martin"/>
        <artiste id="oded" name="Odile Edouard"/>
        <artiste id="fech" name="Freddy Eichelberger"/>
        <artiste id="dsmp" name="David Simpson"/>
    </artistes>
    
    <instruments>
        <instrument id="vdg" name="Viole de gambe"/>
        <instrument id="clv" name="Clavecin"/>
        <instrument id="thb" name="Théorbe"/>
        <instrument id="vl1" name="Violon baroque"/>
        <instrument id="vl2" name="Violon baroque"/>
        <instrument id="org" name="Orgue positif"/>
        <instrument id="vlc" name="Violoncelle baroque"/>
    </instruments>

</codes>
PlagesCD.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<plages>
   
   <plage No="1" vdg="cplu" clv="nspt" 
                 thb="eblq" vl1="fmrt" 
                 vl2="oded" org="fech"> Grave </plage>
                 
   <plage No="2" thb="eblq"  
                 clv="nspt" vl1="fmrt" 
                 vl2="oded" vlc="dsmp"> Presto / Prestissimo </plage>
                 
   <plage No="3" vdg="cplu" clv="nspt" 
                 thb="eblq" vl1="fmrt" 
                 vl2="oded"> Adagio </plage>
                 
   <plage No="4" thb="eblq" vdg="cplu" 
                 clv="nspt" vl1="fmrt" 
                 vlc="dsmp" 
                 org="fech"> Presto Récit de basse </plage>

</plages>
Résultat attendu
-------------------------------------
Christine Plubeau
1 3 4 Viole de gambe
-------------------------------------
Noëlle Spieth
1 2 3 4 Clavecin
-------------------------------------
Eric Bellocq
1 2 3 4 Théorbe
-------------------------------------
Frédéric Martin
1 2 3 4 Violon baroque
-------------------------------------
Odile Edouard
1 2 3 Violon baroque
-------------------------------------
Freddy Eichelberger
1 4 Orgue positif
-------------------------------------
David Simpson
2 4 Violoncelle baroque

Réalisation

<xsl:key name="PlagesParCodesArtistes" 
         match="plage" use="attribute::*" />
<xsl:key name="InstrumentsParCodesInstruments" 
         match="instrument" use="attribute::id" />
    <xsl:template match="artiste">
    <xsl:template match="artiste">
        
        <xsl:call-template name="instancier-NomArtiste">
            <xsl:with-param name="nomArtiste" select="@nom"/>
        </xsl:call-template>
        
        <xsl:call-template name="instancier-NosPlagesAvecCetArtiste">
            <xsl:with-param name="codeArtiste" select="@id"/>
        </xsl:call-template>
        
        <xsl:call-template name="instancier-NomInstrumentDeCetArtiste">
            <xsl:with-param name="codeArtiste" select="@id"/>
        </xsl:call-template>

    </xsl:template>

    </xsl:template>

Instanciation du nom de l'artiste

    <xsl:template name="instancier-NomArtiste">
        <xsl:param name="nomArtiste"/>
        -------------------------------------
        <xsl:value-of select="$nomArtiste"/>
        <xsl:call-template name="instancier-sautLigne"/>
    </xsl:template>

Instanciation des Nos de plages

    <xsl:template name="instancier-NosPlagesAvecCetArtiste">
        <xsl:param name="codeArtiste"/>
        
        <xsl:for-each select="document('PlagesCD.xml')">
        
            <!-- 
                ici le nœud contexte est la racine de l'arbre XML du document 
                contenu dans PlagesCD.xml, car la fonction document() renvoie
                un node-set ne contenant que la racine du document demandé.
            -->

        </xsl:for-each>

    </xsl:template>
    <xsl:template name="instancier-NosPlagesAvecCetArtiste">
        <xsl:param name="codeArtiste"/>
        
        <xsl:for-each select="document('PlagesCD.xml')">
            <xsl:for-each select='key( "PlagesParCodesArtistes", 
                                       $codeArtiste )'>
                <xsl:value-of select="./attribute::No"/>
                <xsl:text> </xsl:text>
            </xsl:for-each>
        </xsl:for-each>

    </xsl:template>

Instanciation des noms d'instruments

key( "InstrumentsParCodesInstruments", $codeInstrument )
    <xsl:template name="instancier-NomInstrumentDeCetArtiste">
        <xsl:param name="codeArtiste"/>
        <xsl:variable name="codeInstrument">
            <xsl:call-template name="instancier-codeInstrument">
                <xsl:with-param name="idArtiste" select="$codeArtiste"/>
            </xsl:call-template>
        </xsl:variable>
                
        <xsl:value-of select='key( "InstrumentsParCodesInstruments", 
                                    $codeInstrument )/attribute::nom' />
                                    
        <xsl:call-template name="instancier-sautLigne"/>
    </xsl:template>
key( "PlagesParCodesArtistes", $idArtiste )
<xsl:variable name="unePlageAvecCetArtiste" 
                          select='key( "PlagesParCodesArtistes", 
                                        $idArtiste )[1]' />
<plage No="3" vdg="cplu" clv="nspt" 
              thb="eblq" vl1="fmrt" 
                         vl2="oded"> Adagio </plage>
$unePlageAvecCetArtiste/attribute::*[ . = $idArtiste ]
    <xsl:template name="instancier-codeInstrument">
        <xsl:param name="idArtiste"/>
        <xsl:for-each select="document('PlagesCD.xml')">
            <xsl:variable name="unePlageAvecCetArtiste" 
                          select='key( "PlagesParCodesArtistes", 
                                        $idArtiste )[1]' />
                          
            <xsl:value-of select="local-name( 
                                  $unePlageAvecCetArtiste/attribute::*
                                  [ . = $idArtiste ] )" />
            
        </xsl:for-each>

    </xsl:template>

Programme complet

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

    <xsl:output  method='text' encoding='ISO-8859-1' />
    
    <xsl:key name="PlagesParCodesArtistes" 
             match="plage" use="attribute::*" />
    
    <xsl:key name="InstrumentsParCodesInstruments" 
             match="instrument" use="attribute::id" />
    
    <xsl:variable name="racinePlages" select="document('plagesCD.xml')" />
    
    
    <!-- ========================================== -->
    <xsl:template name="instancier-NomArtiste">
        <xsl:param name="nomArtiste"/>
        
        <xsl:text>-------------------------------------</xsl:text>
        <xsl:call-template name="instancier-sautLigne"/>
        
        <xsl:value-of select="$nomArtiste"/>
        <xsl:call-template name="instancier-sautLigne"/>
    </xsl:template>
    
    
    <!-- ========================================== -->
    <xsl:template name="instancier-NosPlagesAvecCetArtiste">
        <xsl:param name="codeArtiste"/>
        
        <xsl:for-each select="$racinePlages">
            <xsl:for-each select='key( "PlagesParCodesArtistes", 
                                       $codeArtiste )'>
                <xsl:value-of select="@No"/>
                <xsl:text> </xsl:text>
            </xsl:for-each>
        </xsl:for-each>

    </xsl:template>
    
    
    <!-- ========================================== -->
    <xsl:template name="instancier-NomInstrumentDeCetArtiste">
        <xsl:param name="codeArtiste"/>
        <xsl:variable name="codeInstrument">
            <xsl:call-template name="instancier-codeInstrument">
                <xsl:with-param name="idArtiste" select="$codeArtiste"/>
            </xsl:call-template>
        </xsl:variable>
                
        <xsl:value-of select='key( "InstrumentsParCodesInstruments", 
                                    $codeInstrument )/attribute::nom' />
                                    
        <xsl:call-template name="instancier-sautLigne"/>
    </xsl:template>
    
    
    
    <!-- ========================================== -->
    <xsl:template name="instancier-codeInstrument">
        <xsl:param name="idArtiste"/>
        <xsl:for-each select="$racinePlages">
            <xsl:variable name="unePlageAvecCetArtiste" 
                          select='key( "PlagesParCodesArtistes", 
                                        $idArtiste )[1]' />
                          
            <xsl:value-of select="local-name( 
                                  $unePlageAvecCetArtiste/attribute::*
                                  [ . = $idArtiste ] )" />
            
        </xsl:for-each>

    </xsl:template>
    
    <!-- ========================================== -->
    <xsl:template name="instancier-sautLigne">
    <xsl:text>
</xsl:text>
    </xsl:template>
    
    
    
    <!-- ========================================== -->
    <xsl:template match="artiste">
        
        <xsl:call-template name="instancier-NomArtiste">
            <xsl:with-param name="nomArtiste" select="@nom"/>
        </xsl:call-template>
        
        <xsl:call-template name="instancier-NosPlagesAvecCetArtiste">
            <xsl:with-param name="codeArtiste" select="@id"/>
        </xsl:call-template>
        
        <xsl:call-template name="instancier-NomInstrumentDeCetArtiste">
            <xsl:with-param name="codeArtiste" select="@id"/>
        </xsl:call-template>

    </xsl:template>
    
    
    <!-- ========================================== -->
    <xsl:template match="text()"/>
 
    
</xsl:stylesheet>

Génération d'hyper liens

Motivation

Saison.xml
<?xml version="1.0" encoding="UTF-16"?>
<Saison>

    <Période> Automne 1999 </Période>

    <Manifestations>
        <Concert> 
            <Organisation> Anacréon </Organisation>
            <Date>Samedi 9 Octobre 1999 <Heure> 20H30 </Heure> </Date>
            <Lieu>Chapelle des Ursules</Lieu>
        </Concert> 
        <Théâtre> 
            <Organisation> Masques et Lyres </Organisation>
            <Date>Mardi 19 Novembre 1999 <Heure> 21H </Heure> </Date>
            <Lieu>Salle des Cordeliers</Lieu>
        </Théâtre> 
        <Théâtre> 
            <Organisation> Masques et Lyres </Organisation>
            <Date>Mercredi 20 Novembre 1999 <Heure> 21H30 </Heure> </Date>
            <Lieu>Salle des Cordeliers</Lieu>
        </Théâtre> 
    </Manifestations>
    
    <Adresse>
        <Lieu>Chapelle des Ursules</Lieu>
        9, rue des Ursules - 49000 Angers
    </Adresse>
    
    <Adresse>
        <Lieu>Salle des Cordeliers</Lieu>
        1, rue des Prévoyants de l'avenir - 49000 Angers
    </Adresse>
    
</Saison>

Réalisation avec recherche par clé

<xsl:key name="lieux" match="Adresse//Lieu" use="." />
<a name="#{generate-id(key('lieux', 'Chapelle des Ursules'))}">
<a name="#d0e56">
<a name="{concat('#', generate-id(key('lieux', 'Chapelle des Ursules')))}">
Saison.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0">

    <xsl:output  method='html' encoding='ISO-8859-1' />
    
    <xsl:key name="lieux" match="Adresse//Lieu" use="." />
    
    
    <xsl:template match="/">
        <html>
            <head>
                <title>Programme Saison
                    <xsl:value-of 
                    select="/Saison/Période"/>
                </title>
            </head>
            <body bgcolor="white" text="black">
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>
    
    <xsl:template match="Saison">
        <xsl:apply-templates select="Manifestations"/>
        <H3>Adresses :</H3> 
        <xsl:apply-templates select="Adresse"/>
    </xsl:template>
    
    <xsl:template match="Concert|Théâtre">
        <H3><xsl:value-of select="local-name(.)"/> </H3>
        <p>Date : <xsl:value-of select="Date"/> <br/>
           Lieu : <a href="#{generate-id(key('lieux', ./Lieu))}">
                   <xsl:value-of select="Lieu"/>
                   </a>
        </p>
    </xsl:template>
    
    <xsl:template match="Adresse">
        <p><a name="#{generate-id(key('lieux', ./Lieu))}">
           <xsl:value-of select="Lieu"/>
           </a>
           <br/>
           <xsl:value-of select="./child::text()[2]"/>
        </p>
    </xsl:template>
    
    <xsl:template match="text()"/>
 
    
</xsl:stylesheet>
<xsl:value-of select="./child::text()[2]"/>
Saison.html
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   
      <title>Programme Saison  Automne 1999 </title>
   </head>
   <body bgcolor="white" text="black">
      <H3>Concert</H3>
      <p>Date : Samedi 9 Octobre 1999  20H30  <br>
               Lieu : <a href="#d0e56">Chapelle des Ursules</a></p>
      <H3>Th&eacute;&acirc;tre</H3>
      <p>Date : Mardi 19 Novembre 1999  21H  <br>
               Lieu : <a href="#d0e62">Salle des Cordeliers</a></p>
      <H3>Th&eacute;&acirc;tre</H3>
      <p>Date : Mercredi 20 Novembre 1999  21H30  <br>
               Lieu : <a href="#d0e62">Salle des Cordeliers</a></p>
      <H3>Adresses :</H3>
      <p><a name="#d0e56">Chapelle des Ursules</a><br>
                9, rue des Ursules - 49000 Angers
            
      </p>
      <p><a name="#d0e62">Salle des Cordeliers</a><br>
                1, rue des Pr&eacute;voyants de l'avenir - 49000 Angers
            
      </p>
   </body>
</html>

Réalisation avec recherche par expression XPath

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

    <xsl:output  method='html' encoding='ISO-8859-1' />
    <xsl:strip-space elements="*" />
    
    <xsl:template match="/">
        <html>
            <head>
                <title>
                    Programme Saison 
                    <xsl:value-of select="/Saison/Période"/>
                </title>
            </head>
            <body bgcolor="white" text="black">
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>
    
    <xsl:template match="Saison">
        <xsl:apply-templates select="Manifestations"/>
        <H3>Adresses :</H3> 
        <xsl:apply-templates select="Adresse"/>
    </xsl:template>
    
    <xsl:template match="Concert|Théâtre">
        <H3><xsl:value-of select="local-name(.)"/> </H3>
        <p>Date : <xsl:value-of select="Date"/> <br/>
           Lieu : <a href="#{generate-id(/Saison/Adresse/Lieu
                                         [ . = current()/Lieu ]
                            )}">
                   <xsl:value-of select="Lieu"/>
                   </a>
        </p>
    </xsl:template>
    
    <xsl:template match="Adresse">
        <p><a name="#{generate-id(./Lieu)}">
           <xsl:value-of select="Lieu"/>
           </a><br/>
           <xsl:value-of select="./child::text()"/>
        </p>
    </xsl:template>
    
    <xsl:template match="text()"/>
 
    
</xsl:stylesheet>

Regroupements

Motivation

Fichier aplati
<?xml version="1.0" encoding="UTF-16" ?>
<table name="COMPANY">
NOACA<tab/>CHAR(6)<br/>
LSACA1<tab/>VARCHAR2(35)<br/>
CCPAA1<tab/>NUMBER(4)<br/>
LAACA1<tab/>VARCHAR2(35)<br/>
URL<tab/>VARCHAR2(40)<br/>
STATRAT<tab/>VARCHAR2(1)<br/>
</table>
Fichier restauré
<?xml version="1.0" encoding="UTF-16" ?>
<table name="COMPANY">
    <field>
        <name>NOACA</name>
        <type>CHAR(6)</type>
    </field>
    <field>
        <name>LSACA1</name>
        <type>VARCHAR2(35)</type>
    </field>
    etc.
</table>

Regroupements par valeur ou par position

Des pièces regroupées par surface habitable (regroupement par valeur d'attributs)

maisons.xml
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<maisons>
    <maison id="1">
        <RDC>
            <cuisine surface='40m2'>
                Evier inox. Mobilier encastré.
            </cuisine>
            <WC>
                Lavabo. Cumulus 200L.
            </WC>
            <séjour surface='40m2'>
                Cheminée en pierre. Poutres au plafond. 
                Carrelage terre cuite. Grande baie vitrée.
            </séjour>
            <bureau surface='15m2'>
                Bibliothèque encastrée.
            </bureau>
            <garage/>
        </RDC>
        <étage>
            <terrasse>Palmier en zinc figurant le désert.</terrasse>
            <chambre surface='28m2' fenêtre='3'>
                Carrelage terre cuite poncée.
                <alcôve surface='8m2' fenêtre='1'>
                    Lambris.
                </alcôve>
            </chambre>
            <chambre surface='15m2'>
                Lambris.
            </chambre>
            <salleDeBains surface='15m2'>
                Douche, baignoire, lavabo.
            </salleDeBains>
        </étage>
    </maison>
    <maison id="2">
        <RDC>
            <cuisine surface='28m2'>
                en ruine.
            </cuisine>
            <garage/>
        </RDC>
        <étage>
            <terrasse>
                vue sur la mer
            </terrasse>
            <salleDeBains surface='15m2'>
                Douche.
            </salleDeBains>
        </étage>
    </maison>
    <maison id="3">
        <RDC>
            <séjour surface='40m2'>
                paillasson à l'entrée
            </séjour>
        </RDC>
        <étage>
            <chambre surface='28m2'>
                porte cochère.
            </chambre>
        </étage>
    </maison>
</maisons>
pieces.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<piecesParSurfaces>

   <pieces surface="40m2">
      <cuisine idMaison="1">Evier inox. Mobilier encastré.</cuisine>
      <séjour idMaison="1">Cheminée en pierre. Poutres au plafond. 
                           Carrelage terre cuite. Grande baie vitrée.</séjour>
      <séjour idMaison="3">paillasson à l'entrée</séjour>
   </pieces>
   
   <pieces surface="15m2">
      <bureau idMaison="1">Bibliothèque encastrée.</bureau>
      <chambre idMaison="1">Lambris.</chambre>
      <salleDeBains idMaison="1">Douche, baignoire, lavabo.</salleDeBains>
      <salleDeBains idMaison="2">Douche.</salleDeBains>
   </pieces>
   
   <pieces surface="28m2">
      <chambre idMaison="1">Carrelage terre cuite poncée.</chambre>
      <cuisine idMaison="2">en ruine.</cuisine>
      <chambre idMaison="3">porte cochère.</chambre>
   </pieces>
   
   <pieces surface="8m2">
      <alcôve idMaison="1">Lambris.</alcôve>
   </pieces>
   
</piecesParSurfaces>
<xsl:key name="groupesdeSurfacesParValeurs" 
         match="attribute::surface" 
         use="." />
Création d'un node-set de surfaces toutes différentes
//attribute::surface[
      generate-id() = 
      generate-id( 
         key('groupesdeSurfacesParValeurs', .)[1]
      )
  ]
maisons.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='xml' encoding='ISO-8859-1' indent="yes" />

    <xsl:key name="groupesdeSurfacesParValeurs" 
             match="attribute::surface" 
             use="." />
    
    
    <!-- 
    Etape 1 : constitution d'un ensemble de valeurs toutes différentes
    ================================================================== -->
    
     <xsl:variable name="lesDifférentesSurfaces" 
                  select="//attribute::surface[
                              generate-id() = 
                              generate-id( 
                                  key('groupesdeSurfacesParValeurs', .)[1]
                              )
                            ]" />
    <!-- 
    ================================================================== -->
    
    
    
                  
    <xsl:template match="/">
        <piecesParSurfaces>
            <!-- 
            Etape 2A : parcours des valeurs de cet ensemble
            =============================================== -->
            <xsl:for-each select="$lesDifférentesSurfaces" > <!-- 
            =============================================== -->
            
              <!-- 
                ici le nœud courant est un nœud attribute::surface 
                -->
                
                <xsl:variable name="valeurCourante" select="." />
                
                <pieces surface="{$valeurCourante}">
                    <!-- 
                    Etape 2B : parcours des nœuds ayant cette valeur 
                    ==================================================== -->
                    <xsl:for-each select="key('groupesdeSurfacesParValeurs', 
                                               $valeurCourante)" >     <!-- 
                    ==================================================== -->
                    
                      <!-- 
                        ici le nœud courant est un nœud attribute::surface 
                        -->
                    
                        <xsl:variable name="pieceCourante" 
                                      select="./parent::node()" />
                        
                        <xsl:element name="{local-name($pieceCourante)}">
                            <xsl:attribute name="idMaison">
                                <xsl:value-of select="
                                $pieceCourante/ancestor::maison/@id"/>
                            </xsl:attribute>
                            <xsl:value-of select="
                            normalize-space($pieceCourante/child::text())"/>
                        </xsl:element>
                    </xsl:for-each>
                </pieces>
            </xsl:for-each>
        </piecesParSurfaces>
    </xsl:template>
    
    
</xsl:stylesheet>

Les villes regroupées par pays (regroupement par valeur d'attributs)

villes.xml
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<Villes>
    <Ville nom="Paris" pays="France" />
    <Ville nom="Madrid" pays="Espagne" />
    <Ville nom="Milan" pays="Italie" />
    <Ville nom="Rome" pays="Italie" />
    <Ville nom="Angers" pays="France" />
    <Ville nom="Barcelone" pays="Espagne" />
    <Ville nom="Venise" pays="Italie" />
    <Ville nom="Cordoue" pays="Espagne" />
    <Ville nom="Naples" pays="Italie" />
</Villes>
villes.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='text' encoding='ISO-8859-1' />

    <xsl:key name="groupesDePaysParNoms" 
             match="attribute::pays" 
             use="." />
    
    <!-- 
    Etape 1 : constitution d'un ensemble de valeurs toutes différentes
    ================================================================== -->
    <xsl:variable name="lesDifférentsPays" 
                  select="//attribute::pays[
                              generate-id() = 
                              generate-id( 
                                  key('groupesDePaysParNoms', .)[1]
                              )
                            ]" />
    <!-- 
    ================================================================== -->
    
    <xsl:template match="/">
        <!-- 
        Etape 2A : parcours des valeurs de cet ensemble
        =============================================== -->
        <xsl:for-each select="$lesDifférentsPays"> <!-- 
        =============================================== -->
          <!-- 
            ici le nœud courant est un nœud attribute::pays 
            -->
        - <xsl:value-of select="."/> :
            <xsl:variable name="tousLesAttributsPaysDeMêmeValeur" 
                          select="key('groupesDePaysParNoms', .)" />
            <!-- 
            Etape 2B : parcours des nœuds ayant cette valeur 
            ========================================================= -->
            <xsl:for-each select="$tousLesAttributsPaysDeMêmeValeur"> <!-- 
            ========================================================= -->
              <!-- 
                ici le nœud courant est un nœud attribute::pays 
                -->
                <xsl:variable name="laVilleCorrespondante" 
                              select="./parent::node()" />
                . <xsl:value-of select="$laVilleCorrespondante/@nom"/>
                
            </xsl:for-each>
        </xsl:for-each>
                
    </xsl:template>
    
</xsl:stylesheet>
Résultat
 
        - France :
            
                . Paris
                . Angers 
          
        - Espagne :
            
                . Madrid
                . Barcelone
                . Cordoue 
          
        - Italie :
            
                . Milan
                . Rome
                . Venise
                . Naples

Les instrumentistes regroupés par instruments (regroupement par valeur de nœuds texte)

Concert.xml
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>

<Concert>
    
    <Entête> Les Concerts d'Anacréon </Entête>
    <Date>Mardi 11 Février 2003, 20H30</Date>
    <Lieu>Chapelle des Ursules</Lieu>

    <Ensemble> Hespèrion XXI </Ensemble>

    <Interprète>
        <Nom> Jordi Savall </Nom>
        <Instrument>Dessus de viole</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Wieland Kuijken </Nom>
        <Instrument>Hautecontre de viole</Instrument>
    </Interprète>
    
    <Interprète>
        <Nom> Sophie Watillon </Nom>
        <Instrument>Hautecontre de viole</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Sergi Casademunt </Nom>
        <Instrument>Ténor de viole</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Sylvia Abramowicz </Nom>
        <Instrument>Basse de viole</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Marianne Muller </Nom>
        <Instrument>Basse de viole</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Philippe Pierlot </Nom>
        <Instrument>Basse de viole</Instrument>
    </Interprète>
    
    <TitreConcert>
        Fantasias for the Viols (1680)
    </TitreConcert>
    
    <Compositeur>Henry Purcell</Compositeur>
    
</Concert>
distribution.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='text' encoding='ISO-8859-1' />

    <xsl:key name="groupesInterprètesParInstruments" 
             match="Instrument" 
             use="." />
    
    
    <!-- 
    Etape 1 : constitution d'un ensemble de valeurs toutes différentes
    ================================================================== -->
    
     <xsl:variable name="lesDifférentsInstruments" 
                  select="//Instrument[
                              generate-id() = 
                              generate-id( 
                                  key('groupesInterprètesParInstruments', .)[1]
                              )
                            ]" />
    <!-- 
    ================================================================== -->
    
    
    
                  
    <xsl:template match="/">
        <!-- 
        Etape 2A : parcours des valeurs de cet ensemble
        =============================================== -->
        <xsl:for-each select="$lesDifférentsInstruments" > <!-- 
        =============================================== -->
        
          <!-- 
            ici le nœud courant est un nœud <Instrument> 
            -->
            
            <xsl:variable name="valeurCourante" select="." />
            
            - <xsl:value-of select="$valeurCourante"/>
            
            <!-- 
            Etape 2B : parcours des <Instrument> ayant cette valeur 
            ==================================================== -->
            <xsl:for-each select="key('groupesInterprètesParInstruments', 
                                       $valeurCourante)" >     <!-- 
            ==================================================== -->
            
              <!-- 
                ici le nœud courant est un nœud <Instrument> 
                -->
            
                <xsl:variable name="instrumentiste" 
                              select="./parent::Interprète" />
                . <xsl:value-of select="$instrumentiste/Nom"/>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    
    
</xsl:stylesheet>
Résultat
            - Dessus de viole
                .  Jordi Savall 
            
            - Hautecontre de viole
                .  Wieland Kuijken 
                .  Sophie Watillon 
            
            - Ténor de viole
                .  Sergi Casademunt 
            
            - Basse de viole
                .  Sylvia Abramowicz 
                .  Marianne Muller 
                .  Philippe Pierlot 

Les villes trois par trois (regroupement positionnel)

villes.xml
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<Villes>
    <Ville nom="Paris" pays="France" />
    <Ville nom="Madrid" pays="Espagne" />
    <Ville nom="Milan" pays="Italie" />
    <Ville nom="Rome" pays="Italie" />
    <Ville nom="Angers" pays="France" />
    <Ville nom="Barcelone" pays="Espagne" />
    <Ville nom="Venise" pays="Italie" />
    <Ville nom="Cordoue" pays="Espagne" />
    <Ville nom="Naples" pays="Italie" />
</Villes>
villes.html
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   
      <title> Les villes </title>
   </head>
   <body text="black" bgcolor="white">
      <table>
         <tr>
            <td>Paris</td>
            <td>Madrid</td>
            <td>Milan</td>
         </tr>
         <tr>
            <td>Rome</td>
            <td>Angers</td>
            <td>Barcelone</td>
         </tr>
         <tr>
            <td>Venise</td>
            <td>Cordoue</td>
            <td>Naples</td>
         </tr>
      </table>
   </body>
</html>
<xsl:key name="lesVillesParPosition" 
             match="Ville" 
             use="??" />
preceding-sibling::Ville
count( preceding-sibling::Ville )
<xsl:key name="lesVillesParPosition" 
             match="Ville" 
             use="floor( count(preceding-sibling::Ville)  div 3 )" />
    <xsl:variable name="lesDifférentsGroupesDeVilles" 
                  select="//Ville[ 
                             ((position() - 1)  mod 3) = 0
                            ]" />
villes.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='html' encoding='ISO-8859-1' />
             
    <xsl:variable name="facteurDeRegroupement" select="3"/>
              
    <xsl:key name="lesVillesParPosition" 
             match="Ville" 
             use="floor( count(preceding-sibling::Ville)  div 3 )" />
             
    <!-- 
    Etape 1 : constitution d'un ensemble de valeurs toutes différentes
    ================================================================== -->
    <xsl:variable name="lesDifférentsGroupesDeVilles" 
                  select="//Ville[ 
                             ((position() - 1)  mod $facteurDeRegroupement) = 0
                            ]" />
    <!-- 
    ================================================================== -->
    
    <xsl:template match="Villes">
        
        <table>
        <!-- 
        Etape 2A : parcours des valeurs de cet ensemble
        =============================================== -->
        <xsl:for-each select="$lesDifférentsGroupesDeVilles"> <!-- 
        =============================================== -->
          <!-- 
            ici le noeud courant est un noeud Ville 
            (la première de chaque ligne du tableau)
            Sa valeur de clé est donnée par position() - 1
            -->
            
            <xsl:variable name="valClé" select="position() - 1" />
            
            <tr>
            <!-- 
            Etape 2B : parcours des noeuds ayant cette valeur 
            ========================================================= -->
            <xsl:for-each select="key('lesVillesParPosition', $valClé)"> <!-- 
            ========================================================= -->
              <!-- 
                ici le noeud courant est une ville 
                -->
                <td><xsl:value-of select="@nom"/></td>
                
            </xsl:for-each>
            </tr>
        </xsl:for-each>
        </table>
        
    </xsl:template>
    
    <!--   -->
    <xsl:template match="/">
        <html>
            <head>
            <title> Les villes </title>
            </head>
            <body text="black" bgcolor="white">
            <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>
    
</xsl:stylesheet>

Regroupements hiérarchiques

Exemple générique

flatDatas.xml
<?xml version="1.0" encoding="UTF-16" ?>
<recordset>
    <record/>
        <data/>
        <data/>
    <record/>
        <data/>
    <record/>
        <data/>
        <data/>
        <data/>
</recordset>
Datas.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<recordset>
   <record>
      <data/>
      <data/>
   </record>
   <record>
      <data/>
   </record>
   <record>
      <data/>
      <data/>
      <data/>
   </record>
</recordset>
Première étape
Première étape : initialisation de la clé des enfants directs
<xsl:key 
    name="lesEnfantsDirects" 
    match="record" 
    use="generate-id( parent::recordset  )" />
         
<xsl:key
    name="lesEnfantsDirects" 
    match="data"
    use="generate-id( preceding-sibling::record[1]  )" />
Deuxième étape
Deuxième étape : parcours hiérarchique (début)
<xsl:template match="recordset" >
    <recordset>
        <xsl:apply-templates  
             select="key('lesEnfantsDirects', generate-id(.))"/>
    </recordset>
</xsl:template>
Deuxième étape : parcours hiérarchique (suite)
<xsl:template match="record" >
    <record>
        <xsl:apply-templates  
             select="key('lesEnfantsDirects', generate-id(.))"/>
    </record>
</xsl:template>
unflatten.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='xml' encoding='ISO-8859-1' indent='yes' />
    
    <!--
    ========================================================================
    Reconstitution des relations hiérarchiques
    ========================================================================
    -->
    
    <xsl:key name="lesEnfantsDirects" 
             match="record" 
             use="generate-id( parent::recordset  )" />
             
    <xsl:key
        name="lesEnfantsDirects" 
        match="data"
        use="generate-id( preceding-sibling::record[1]  )" />
          
          
    <!--
    ========================================================================
    Parcours récursif de la hiérarchie
    ========================================================================
    -->
      

    <xsl:template match="/">
            <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="recordset" >
        <recordset>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </recordset>
    </xsl:template>
    
    <xsl:template match="record" >
        <record>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </record>
    </xsl:template>
    
    <!--
    ========================================================================
    Eléments terminaux de la hiérarchie
    ========================================================================
    -->
    
    <xsl:template match="data" >
        <xsl:copy-of select="."/>
    </xsl:template>
    
    
</xsl:stylesheet>

Reconstitution hiérarchique d'un texte

texte.xml
<?xml version="1.0" encoding="UTF-16" ?>
<document>
    <titreSection1> titre A </titreSection1>
        <p> para 1 </p>
        <titreSection2> titre A.1 </titreSection2>
            <p> para 2 </p>
            <p> para 3 </p>
            <p> para 4 </p>
        <titreSection2> titre A.2 </titreSection2>
            <p> para 5 </p>
            <titreSection3> titre A.2.1 </titreSection3>
                <p> para 6 </p>
                <p> para 7 </p>
        <titreSection2> titre A.3 </titreSection2>
            <p> para 8 </p>
    <titreSection1> titre B </titreSection1>
        <titreSection2> titre B.1 </titreSection2>
            <titreSection3> titre B.1.1 </titreSection3>
                <p> para 9 </p>
            <titreSection3> titre B.1.2 </titreSection3>
                <p> para 10 </p>
        <titreSection2> titre B.2 </titreSection2>
            <p> para 11 </p>
</document>
texteReconstruit.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<Document>
   <Section1>
      <titre> titre A </titre>
      <p> para 1 </p>
      <Section2>
         <titre> titre A.1 </titre>
         <p> para 2 </p>
         <p> para 3 </p>
         <p> para 4 </p>
      </Section2>
      <Section2>
         <titre> titre A.2 </titre>
         <p> para 5 </p>
         <Section3>
            <titre> titre A.2.1 </titre>
            <p> para 6 </p>
            <p> para 7 </p>
         </Section3>
      </Section2>
      <Section2>
         <titre> titre A.3 </titre>
         <p> para 8 </p>
      </Section2>
   </Section1>
   <Section1>
      <titre> titre B </titre>
      <Section2>
         <titre> titre B.1 </titre>
         <Section3>
            <titre> titre B.1.1 </titre>
            <p> para 9 </p>
         </Section3>
         <Section3>
            <titre> titre B.1.2 </titre>
            <p> para 10 </p>
         </Section3>
      </Section2>
      <Section2>
         <titre> titre B.2 </titre>
         <p> para 11 </p>
      </Section2>
   </Section1>
</Document>
Ebauche de la transformation
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='xml' encoding='ISO-8859-1' indent='yes' />
    
    <!--
    ========================================================================
    Reconstitution des relations hiérarchiques
    ========================================================================
    -->
    
    <xsl:key name="lesEnfantsDirects" 
             match="??" 
             use="??" />
             
    <xsl:key ... /> 
          
          
    <!--
    ========================================================================
    Parcours récursif de la hiérarchie
    ========================================================================
    -->
       
    
    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="document" >
        <Document>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Document>
    </xsl:template>
    
    <xsl:template match="titreSection1" >
        <Section1>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section1>
    </xsl:template>
    
    <xsl:template match="titreSection2" >
        <Section2>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section2>
    </xsl:template>
    
    <xsl:template match="titreSection3" >
        <Section3>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section3>
    </xsl:template> 
    
    <!--
    ========================================================================
    Eléments terminaux de la hiérarchie
    ========================================================================
    -->
    
    <xsl:template match="p" >
        <p>
            <xsl:value-of select="."/>
        </p>
    </xsl:template>
    
</xsl:stylesheet>
p
p[preceding-sibling::*[not(self::p)]]
p[preceding-sibling::*[not(self::p)][1][self::titreSection1]]
<xsl:key
    name="lesEnfantsDirects" 
    match="titreSection2 | 
           p[preceding-sibling::*[not(self::p)][1][self::titreSection1]]"
    use="generate-id( preceding-sibling::titreSection1[1]  )" />
texte.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='xml' encoding='ISO-8859-1' indent='yes' />
    
    <!--
    ========================================================================
    Reconstitution des relations hiérarchiques
    ========================================================================
    -->
    
    <xsl:key name="lesEnfantsDirects" 
             match="titreSection1" 
             use="generate-id( parent::document  )" />
             
    <xsl:key
        name="lesEnfantsDirects" 
        match="titreSection2 | 
               p[preceding-sibling::*[not(self::p)][1][self::titreSection1]]"
        use="generate-id( preceding-sibling::titreSection1[1]  )" />
             
    <xsl:key 
        name="lesEnfantsDirects" 
        match="titreSection3 | 
               p[preceding-sibling::*[not(self::p)][1][self::titreSection2]]" 
        use="generate-id( preceding-sibling::titreSection2[1]  )" />
             
    <xsl:key 
        name="lesEnfantsDirects" 
        match="p[preceding-sibling::*[not(self::p)][1][self::titreSection3]]" 
        use="generate-id( preceding-sibling::titreSection3[1]  )" /> 
          
          
    <!--
    ========================================================================
    Parcours récursif de la hiérarchie
    ========================================================================
    -->
       
    
    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="document" >
        <Document>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Document>
    </xsl:template>
    
    <xsl:template match="titreSection1" >
        <Section1>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section1>
    </xsl:template>
    
    <xsl:template match="titreSection2" >
        <Section2>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section2>
    </xsl:template>
    
    <xsl:template match="titreSection3" >
        <Section3>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section3>
    </xsl:template> 
    
    <!--
    ========================================================================
    Eléments terminaux de la hiérarchie
    ========================================================================
    -->
    
    <xsl:template match="p" >
        <p>
            <xsl:value-of select="."/>
        </p>
    </xsl:template>
    
    
</xsl:stylesheet>
texte.xml
<?xml version="1.0" encoding="UTF-16" ?>
<document>
    <titreSection1> titre A </titreSection1>
        <p> para 1 </p>
        <figure href="A.gif"/>
        <titreSection2> titre A.1 </titreSection2>
            <p> para 2 </p>
            <p> para 3 </p>
            <figure href="A.1.gif"/>
            <p> para 4 </p>
        <titreSection2> titre A.2 </titreSection2>
            <p> para 5 </p>
            <titreSection3> titre A.2.1 </titreSection3>
                <p> para 6 </p>
                <p> para 7 </p>
                <figure href="A.2.1.gif"/>
        <titreSection2> titre A.3 </titreSection2>
            <p> para 8 </p>
    <titreSection1> titre B </titreSection1>
        <figure href="B.gif"/>
        <titreSection2> titre B.1 </titreSection2>
            <titreSection3> titre B.1.1 </titreSection3>
                <p> para 9 </p>
            <titreSection3> titre B.1.2 </titreSection3>
                <p> para 10 </p>
        <titreSection2> titre B.2 </titreSection2>
            <p> para 11 </p>
            <figure href="B.2.gif"/>
</document>
<xsl:key
    name="lesEnfantsDirects" 
    match="titreSection2 | 
           *[self::p or self::figure]
           [preceding-sibling::*
               [not(self::p)]
               [not(self::figure)]
               [1]
               [self::titreSection1]
           ]"
    use="generate-id( preceding-sibling::titreSection1[1]  )" />
<xsl:key
    name="lesEnfantsDirects" 
    match="titreSection2 | 
           p[preceding-sibling::*[not(self::p)][1][self::titreSection1]]"
    use="generate-id( preceding-sibling::titreSection1[1]  )" />
<xsl:key
    name="lesEnfantsDirects" 
    match="titreSection2 | 
           *[self::p] 
           [preceding-sibling::*
               [not(self::p)]
               [1]
               [self::titreSection1]
           ]"
    use="generate-id( preceding-sibling::titreSection1[1]  )" />
texte.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='xml' encoding='ISO-8859-1' indent='yes' />
    
    <!--
    ========================================================================
    Reconstitution des relations hiérarchiques
    ========================================================================
    -->
    
    <xsl:key name="lesEnfantsDirects" 
             match="titreSection1" 
             use="generate-id( parent::document  )" />
             
             
    <xsl:key
        name="lesEnfantsDirects" 
        match="titreSection2 | 
               *[self::p or self::figure]
               [preceding-sibling::*
                   [not(self::p)]
                   [not(self::figure)]
                   [1]
                   [self::titreSection1]
               ]"
        use="generate-id( preceding-sibling::titreSection1[1]  )" />
             
    <xsl:key 
        name="lesEnfantsDirects" 
        match="titreSection3 | 
               *[self::p or self::figure]
               [preceding-sibling::*
                   [not(self::p)]
                   [not(self::figure)]
                   [1]
                   [self::titreSection2]
               ]" 
        use="generate-id( preceding-sibling::titreSection2[1]  )" />
             
    <xsl:key 
        name="lesEnfantsDirects" 
        match="*[self::p or self::figure]
               [preceding-sibling::*[
                   not(self::p)]
                   [not(self::figure)]
                   [1]
                   [self::titreSection3]
               ]" 
        use="generate-id( preceding-sibling::titreSection3[1]  )" /> 
          
          
    <!--
    ========================================================================
    Parcours récursif de la hiérarchie
    ========================================================================
    -->
       
    
    <xsl:template match="/">
            <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="document" >
        <document>
            <xsl:apply-templates  
            select="key('lesEnfantsDirects', generate-id(.))"/>
        </document>
    </xsl:template>
    
    <xsl:template match="titreSection1" >
        <Section1>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
            select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section1>
    </xsl:template>
    
    <xsl:template match="titreSection2" >
        <Section2>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
            select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section2>
    </xsl:template>
    
    <xsl:template match="titreSection3" >
        <Section3>
            <titre><xsl:value-of select="."/></titre>
            <xsl:apply-templates  
            select="key('lesEnfantsDirects', generate-id(.))"/>
        </Section3>
    </xsl:template> 
    
    <!--
    ========================================================================
    Eléments terminaux de la hiérarchie
    ========================================================================
    -->
    
    <xsl:template match="p" >
        <p>
            <xsl:value-of select="."/>
        </p>
    </xsl:template>
    
    <xsl:template match="figure" >
        <xsl:copy-of select="."/>
    </xsl:template>
    
    
</xsl:stylesheet>

Exemple atypique

company.xml
<?xml version="1.0" encoding="UTF-16"?>
<table name="COMPANY">
    NOACA<tab/>CHAR(6)<br/>
    LSACA1<tab/>VARCHAR2(35)<br/>
    CCPAA1<tab/>NUMBER(4)<br/>
    LAACA1<tab/>VARCHAR2(35)<br/>
    URL<tab/>VARCHAR2(40)<br/>
    STATRAT<tab/>VARCHAR2(1)<br/>
</table>
restoredCompany.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<table name="COMPANY">
   <field>
      <name>NOACA</name>
      <type>CHAR(6)</type>
   </field>
   <field>
      <name>LSACA1</name>
      <type>VARCHAR2(35)</type>
   </field>
   <field>
      <name>CCPAA1</name>
      <type>NUMBER(4)</type>
   </field>
   <field>
      <name>LAACA1</name>
      <type>VARCHAR2(35)</type>
   </field>
   <field>
      <name>URL</name>
      <type>VARCHAR2(40)</type>
   </field>
   <field>
      <name>STATRAT</name>
      <type>VARCHAR2(1)</type>
   </field>
</table>
restoredCompany.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output  method='xml' encoding='ISO-8859-1' indent='yes' />

    <!--
    ========================================================================
    Reconstitution des relations hiérarchiques
    ========================================================================
    -->
    
    <xsl:key name="lesEnfantsDirects" 
             match="br" 
             use="generate-id( parent::table )" />
             
    <xsl:key
        name="lesEnfantsDirects" 
        match="tab"
        use="generate-id( following-sibling::br[1]  )" />
          
          
    <!--
    ========================================================================
    Parcours récursif de la hiérarchie
    ========================================================================
    -->
      

    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="table" >
        <xsl:copy>
            <xsl:for-each select="attribute::*">
                <xsl:copy/>
            </xsl:for-each>

            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
            
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="br" >
        <field>
            <xsl:apply-templates  
                 select="key('lesEnfantsDirects', generate-id(.))"/>
            <type><xsl:value-of select="preceding-sibling::text()[1]"/></type>
        </field>
    </xsl:template>
    
    <!--
    ========================================================================
    Eléments terminaux de la hiérarchie
    ========================================================================
    -->
    
    <xsl:template match="tab" >
        <name>
        <xsl:value-of select="normalize-space(preceding-sibling::text()[1])"/>
        </name>
    </xsl:template>
    
    
</xsl:stylesheet>

Génération d'une feuille de style par une autre feuille de style

Motivation

Exemple

BaseProduits.xml
<?xml version="1.0" encoding="UTF-16"?>
<BaseProduits>

    <LesProduits>
    
        <Livre ref="vernes1" NoISBN="193335" gamme="roman" media="papier">
            <refOeuvres>
                <Ref valeur="20000lslm"/>
            </refOeuvres>
            <Prix valeur="40.5" monnaie="FF"/>
            <Prix valeur="5" monnaie="£"/>
        </Livre>
    
        <Livre ref="boileaunarcejac1" NoISBN="533791" gamme="roman" 
                                                     media="papier">
            <refOeuvres>
                <Ref valeur="liatlc.bn"/>
            </refOeuvres>
            <Prix valeur="30" monnaie="FF"/>
            <Prix valeur="3" monnaie="£"/>
        </Livre>
    
        <Enregistrement ref="marais1" RefEditeur="LC000280" 
                                              gamme="violedegambe" media="CD">
            <refOeuvres>
                <Ref valeur="marais.folies"/>
                <Ref valeur="marais.pieces1685"/>
            </refOeuvres>
            <Interprètes>
                <Interprète nom="Jonathan Dunford">
                    <Role xml:lang="fr"> Basse de viole </Role>
                    <Role xml:lang="en"> Bass Viol </Role>
                </Interprète>
                <Interprète nom="Sylvia Abramowicz">
                    <Role xml:lang="fr"> Basse de viole </Role>
                    <Role xml:lang="en"> Bass Viol </Role>
                </Interprète>
                <Interprète nom="Benjamin Perrot">
                    <Role xml:lang="fr"> Théorbe et guitare baroque </Role>
                    <Role xml:lang="en"> Theorbo and baroque guitar </Role>
                </Interprète>
                <Interprète nom="Stéphane Fuget">
                    <Role xml:lang="fr"> Clavecin </Role>
                    <Role xml:lang="en"> Harpsichord </Role>
                </Interprète>
            </Interprètes>
            <Titre 
            xml:lang="fr"> Les Folies d'Espagne et pièces inédites </Titre>
            <Titre 
            xml:lang="en"> Folies d'Espagne and unedited music </Titre>
            <Prix valeur="140" monnaie="FF"/>
            <Prix valeur="13" monnaie="£"/>
        </Enregistrement>
    
        <Matériel ref="HarKar1" refConstructeur="XL-FZ158BK" gamme="lecteurCD" 
                                                               marque="HarKar">
            <refCaractéristiques>
                <Ref valeur="caracHarKar1"/>
            </refCaractéristiques>
            <Prix valeur="4500" monnaie="FF"/>
            <Prix valeur="400" monnaie="£"/>
        </Matériel>
        
    </LesProduits>
    
    <LesOeuvres>
        ...
    </LesOeuvres>
    
    <LesAuteurs>
        ...
    </LesAuteurs>
    
    <LesGammes>
        ...
    </LesGammes>
    
    <LesMarques>
        ...
    </LesMarques>
    
    <LesCaractéristiques>
        ...
    </LesCaractéristiques>
    
</BaseProduits>
XPathExpressions.xml
<?xml version="1.0" encoding="UTF-16"?>

<Expressions sourceFile="BaseProduits.xml">
    
    <XPath
        id="1"
        contextNode="Enregistrement"
        expression="descendant::Interprète[attribute::nom = 
                                           'Sylvia Abramowicz']/child::Role"
    />
    
    <XPath
        id="2"
        contextNode="Enregistrement"
        expression="descendant::Interprète[position() = 2] /attribute::nom"
    />
    
    <XPath
        id="3"
        contextNode="BaseProduits"
        expression="descendant::Livre[attribute::ref = 'vernes1']/
                                                 child::Prix/attribute::valeur"
    />
    
    <XPath
        id="4"
        contextNode="Enregistrement"
        expression="descendant::Titre[attribute::xml:lang = 'en']"
    />
    
    <XPath
        id="5"
        contextNode="BaseProduits"
        expression="descendant::Livre[attribute::ref = 'vernes1']/
                      child::Prix[attribute::monnaie = 'FF']/attribute::valeur"
    />
    
</Expressions>
Ligne de commande
xpath XPathExpressions.xml
Résultat
=== id = 1 ===
                
{
    -- contextNode="Enregistrement"
    -- expression="descendant::Interprète[attribute::nom = 
                                             'Sylvia Abramowicz']/child::Role"
         Basse de viole 
        --
         Bass Viol 
        --
        
}
        
=== id = 2 ===
                
{
    -- contextNode="Enregistrement"
    -- expression="descendant::Interprète[position() = 2] /attribute::nom"
        Sylvia Abramowicz
        --
        
}
        
=== id = 3 ===
                
{
    -- contextNode="BaseProduits"
    -- expression="descendant::Livre[attribute::ref = 'vernes1']/
                                            child::Prix/attribute::valeur"
        40.5
        --
        5
        --
        
}
        
=== id = 4 ===
                
{
    -- contextNode="Enregistrement"
    -- expression="descendant::Titre[attribute::xml:lang = 'en']"
         Folies d'Espagne and unedited music 
        --
        
}
        
=== id = 5 ===
                
{
    -- contextNode="BaseProduits"
    -- expression="descendant::Livre[attribute::ref = 'vernes1']/
              child::Prix[attribute::monnaie = 'FF']/attribute::valeur"
        40.5
        --
        
}
script Xpath
java -classpath "C:\Program Files\JavaSoft\SAXON\saxon.jar;" 
                              com.icl.saxon.StyleSheet -o XPathExpressions.xsl 
                                  XPathExpressions.xml ../XPathInterpretor.xsl

call temp.bat
script temp.bat
java -classpath "C:\Program Files\JavaSoft\SAXON\saxon.jar;"
                                         com.icl.saxon.StyleSheet  -o out.memo
                                         BaseProduits.xml XPathExpressions.xsl
XPathExpressions.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<aaa:stylesheet xmlns:aaa="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

   <aaa:output method="text" encoding="ISO-8859-1"/>
   
   <-- ========================= 1 =========================== -->
   <aaa:template match="/">
=== id = 1 ===
                <aaa:apply-templates mode="M1"/>
=== id = 2 ===
                <aaa:apply-templates mode="M2"/>
=== id = 3 ===
                <aaa:apply-templates mode="M3"/>
=== id = 4 ===
                <aaa:apply-templates mode="M4"/>
=== id = 5 ===
                <aaa:apply-templates mode="M5"/>
   </aaa:template>
   <-- ========================= 1 =========================== -->
   
   
   <-- ========================= 2 =========================== -->
   <aaa:template match="text()" mode="M1"/>
   <aaa:template match="text()" mode="M2"/>
   <aaa:template match="text()" mode="M3"/>
   <aaa:template match="text()" mode="M4"/>
   <aaa:template match="text()" mode="M5"/>
   <-- ========================= 2 =========================== -->
   
   
   
   <-- ========================= 3 =========================== -->
   <aaa:template match="Enregistrement" mode="M1">
{
    -- contextNode="Enregistrement"
    -- expression="descendant::Interprète[attribute::nom = 
                                              'Sylvia Abramowicz']/child::Role"
        <aaa:for-each select="descendant::Interprète[
                            attribute::nom = 'Sylvia Abramowicz']/child::Role">
        <aaa:value-of select="."/>
        --
        </aaa:for-each>
}
   </aaa:template>
        
   <!-- - - - - - - - - - - - - - - - - - - - - -->
   
   <aaa:template match="Enregistrement" mode="M2">
{
    -- contextNode="Enregistrement"
    -- expression="descendant::Interprète[position() = 2] /attribute::nom"
        <aaa:for-each select="descendant::Interprète[
                                          position() = 2] /attribute::nom">
        <aaa:value-of select="."/>
        --
        </aaa:for-each>
}
   </aaa:template>
   
   <!-- - - - - - - - - - - - - - - - - - - - - -->
   
   <aaa:template match="BaseProduits" mode="M3">
{
    -- contextNode="BaseProduits"
    -- expression="descendant::Livre[attribute::ref = 'vernes1']/
                                                child::Prix/attribute::valeur"
        <aaa:for-each select="descendant::Livre[
                    attribute::ref = 'vernes1']/child::Prix/attribute::valeur">
        <aaa:value-of select="."/>
        --
        </aaa:for-each>
}
   </aaa:template>
        
   <!-- - - - - - - - - - - - - - - - - - - - - -->
   
   <aaa:template match="Enregistrement" mode="M4">
{
    -- contextNode="Enregistrement"
    -- expression="descendant::Titre[attribute::xml:lang = 'en']"
        <aaa:for-each select="descendant::Titre[attribute::xml:lang = 'en']">
        <aaa:value-of select="."/>
        --
        </aaa:for-each>
}
   </aaa:template>
        
   <!-- - - - - - - - - - - - - - - - - - - - - -->
   
   <aaa:template match="BaseProduits" mode="M5">
{
    -- contextNode="BaseProduits"
    -- expression="descendant::Livre[attribute::ref = 'vernes1']/
                     child::Prix[attribute::monnaie = 'FF']/attribute::valeur"
        <aaa:for-each select="descendant::Livre[attribute::ref = 
         'vernes1']/child::Prix[attribute::monnaie = 'FF']/attribute::valeur">
        <aaa:value-of select="."/>
        --
        </aaa:for-each>
}
   </aaa:template>
    
   <-- ========================= 3 =========================== -->
</aaa:stylesheet>
<!-- 2 -->
<xsl:for-each select="XPath">
    <aaa:template>
        <xsl:attribute name="match">text()</xsl:attribute>
        <xsl:attribute name="mode">M<xsl:value-of select="@id"/></xsl:attribute>
    </aaa:template>
</xsl:for-each>
<!-- /2 -->
<xsl:stylesheet 
    xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" 
    xmlns:aaa = "http://machin"
    version   = "1.0">
<xsl:namespace-alias stylesheet-prefix="aaa" result-prefix="xsl"/>
<xsl:document href="temp.bat" method="text">
    <xsl:text>java -classpath "C:\Program Files\JavaSoft\SAXON\saxon.jar;" </xsl:text>
    <xsl:text>com.icl.saxon.StyleSheet  -o out.memo </xsl:text> 
    <xsl:value-of select="/Expressions/@sourceFile"/>
    <xsl:text> XPathExpressions.xsl</xsl:text>
</xsl:document>
XPathInterpretor.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet 
    xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" 
    xmlns:aaa= "http://machin"
    version   = "1.1"> <!-- compatibilité Saxon 6.5 -->
    

    <xsl:output  method='xml' encoding='ISO-8859-1' indent='yes' />
    
    <xsl:namespace-alias stylesheet-prefix="aaa" result-prefix="xsl"/>

 
    <xsl:template match='/'>
        <aaa:stylesheet 
            xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" 
            version   = "1.0">
            
        <aaa:output method='text' encoding="ISO-8859-1"/>
        
    
            <xsl:document href="temp.bat" method="text">
                <xsl:text>java -classpath "C:\Program Files\JavaSoft\SAXON\saxon.jar;" </xsl:text>
                <xsl:text>com.icl.saxon.StyleSheet  -o out.memo </xsl:text> 
                <xsl:value-of select="/Expressions/@sourceFile"/>
                <xsl:text> XPathExpressions.xsl</xsl:text>
            </xsl:document>
            
            <xsl:apply-templates/>
            
        </aaa:stylesheet>
        
    </xsl:template>
    
    
    <xsl:template match='Expressions'>
    
        <!-- 1 -->
        <aaa:template>
            <xsl:attribute name="match">/</xsl:attribute>
            <xsl:for-each select="XPath">
=== id = <xsl:value-of select="@id"/> ===
                <aaa:apply-templates>
                    <xsl:attribute name="mode">M<xsl:value-of select="@id"/>
                    </xsl:attribute>
                </aaa:apply-templates>
            </xsl:for-each>
        </aaa:template>
        <!-- /1 -->
        
        <!-- 2 -->
        <xsl:for-each select="XPath">
            <aaa:template>
                <xsl:attribute name="match">text()</xsl:attribute>
                <xsl:attribute name="mode">M<xsl:value-of select="@id"/>
                </xsl:attribute>
            </aaa:template>
        </xsl:for-each>
        <!-- /2 -->
        
        <!-- 3 -->
        <xsl:for-each select="XPath">
        
            <aaa:template>
                <xsl:attribute name="match">
                    <xsl:value-of select="@contextNode"/>
                </xsl:attribute>
                <xsl:attribute name="mode">M<xsl:value-of select="@id"/>
                </xsl:attribute>
{
    -- contextNode="<xsl:value-of select="@contextNode"/>"
    -- expression="<xsl:value-of select="@expression"/>"
        <aaa:for-each>
            <xsl:attribute name="select"><xsl:value-of select="@expression"/>
            </xsl:attribute>
            <aaa:value-of>
                <xsl:attribute name="select">.</xsl:attribute>
            </aaa:value-of>
        --
        </aaa:for-each>
}
        </aaa:template>
        </xsl:for-each>
        <!-- /3 -->
        
    </xsl:template>
    
</xsl:stylesheet>

Génération de pages HTML dynamiques

Motivation

fond.xml
<?xml version="1.0" encoding="UTF-16"?>
<html>
    <head>
        <title>Les Concerts Anacréon</title>
    </head>
    <body>
    
        <H1 align="center"> Concert le <dateConcert/> </H1>
        <H4 align="center"> <lieuConcert/> </H4>
        <H2 align="center"> Ensemble <ensemble/> </H2>
        
        <listeMusiciens>
            <p>
                <musicien/>, <instrument/>
            </p>
        </listeMusiciens>
        
        <H3> 
            Oeuvres de <listeCompositeurs/>
        </H3>
    
    </body>
</html>
<listeMusiciens>
    <p>
        <musicien/>, <instrument/>
    </p>
</listeMusiciens>
Annonce.xml
<?xml version="1.0" encoding="UTF-16"?>

<Annonce>
    
    <Date>
        <Jour>Jeudi</Jour>
        <Quantième>17</Quantième>
        <Mois>Janvier</Mois>
        <Année>2002</Année>
        <Heure>20H30</Heure>
    </Date>
    <Lieu>Chapelle des Ursules</Lieu>

    <Ensemble>A deux violes esgales</Ensemble>

    <Interprète>
        <Nom> Jonathan Dunford </Nom>
        <Instrument>Basse de viole</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Sylvia Abramowicz </Nom>
        <Instrument>Basse de viole</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Benjamin Perrot </Nom>
        <Instrument>Théorbe</Instrument>
    </Interprète>

    <Interprète>
        <Nom> Freddy Eichelberger </Nom>
        <Instrument>Clavecin</Instrument>
    </Interprète>
    
    <Compositeurs>
        M. Marais, D. Castello, F. Rognoni
    </Compositeurs>
    
</Annonce>

Réalisation

<xsl:template match="child::node()|attribute::*" priority="-10">
    <xsl:copy>
        <xsl:apply-templates select="attribute::*" />
        <xsl:apply-templates select="child::node()" />
    </xsl:copy>
</xsl:template>
<xsl:param name="annonceFileRef">Annonce.xml</xsl:param>
<xsl:variable name="Annonce" select="document($annonceFileRef)/Annonce"/>

<xsl:template match='dateConcert'>
     
    <xsl:value-of select="$Annonce/Date/Jour" />
    <xsl:text> </xsl:text>
    
    <xsl:value-of select="$Annonce/Date/Quantième" />
    <xsl:text> </xsl:text>
    
    <xsl:value-of select="$Annonce/Date/Mois" />
    <xsl:text> </xsl:text>
    
    <xsl:value-of select="$Annonce/Date/Année" />
    <xsl:text> </xsl:text>
    
    <xsl:value-of select="$Annonce/Date/Heure" />
    
</xsl:template>

<xsl:template match='lieuConcert'>
    <xsl:value-of select="$Annonce/Lieu" />
</xsl:template>

<xsl:template match='ensemble'>
    <xsl:value-of select="$Annonce/Ensemble" />
</xsl:template>

<xsl:template match='listeCompositeurs'> 
    <xsl:value-of select="$Annonce/Compositeurs" />
</xsl:template>
<p>
    <musicien/>, <instrument/>
</p>
<xsl:template match='listeMusiciens'>
    <xsl:for-each select="$Annonce/Interprète">
        <xsl:variable name="current-Interprète" select="."/>
        ...
    </xsl:for-each>
</xsl:template>
<xsl:template match='listeMusiciens'>
    <xsl:variable name="current-listeMusiciens" select="."/> <!-- (1) -->
    
    <xsl:for-each select="$Annonce/Interprète">
        <xsl:variable name="current-Interprète" select="."/>
        <xsl:for-each select="$current-listeMusiciens/p"> <!-- (2) -->
            <xsl:copy>
                ...
            </xsl:copy>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>
<xsl:template match='listeMusiciens'>
    <xsl:variable name="current-listeMusiciens" select="."/>
    
    <xsl:for-each select="$Annonce/Interprète">
        <xsl:variable name="current-Interprète" select="."/>
        <xsl:for-each select="$current-listeMusiciens/p">
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

<xsl:template match='musicien'>
    <xsl:value-of select="???" />
</xsl:template>
<xsl:template match='listeMusiciens'>
    <xsl:variable name="current-listeMusiciens" select="."/>
    
    <xsl:for-each select="$Annonce/Interprète">
        <xsl:variable name="current-Interprète" select="."/>
        <xsl:for-each select="$current-listeMusiciens/p">
            <xsl:copy>
                <xsl:apply-templates>
                    <xsl:with-param name="interprete" 
                                    select="$current-Interprète" />
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

<xsl:template match='musicien'>
    <xsl:param name="interprete"/>
    <xsl:value-of select="$interprete/Nom" />
</xsl:template>
<xsl:template match='instrument'>
    <xsl:param name="interprete"/>
    <xsl:value-of select="$interprete/Instrument" />
</xsl:template>
AnnonceConcert.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                version="1.0">

    <xsl:output  method='html' encoding='ISO-8859-1' />
    
    <xsl:param name="annonceFileRef">Annonce.xml</xsl:param>
    
    <xsl:variable name="Annonce" select="document($annonceFileRef)/Annonce"/>
        
    <xsl:template match="child::node()|attribute::*" priority="-10">
        <xsl:copy>
            <xsl:apply-templates select="attribute::*" />
            <xsl:apply-templates select="child::node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match='dateConcert'>
         
        <xsl:value-of select="$Annonce/Date/Jour" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Quantième" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Mois" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Année" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Heure" />
        
    </xsl:template>
    
    <xsl:template match='lieuConcert'>
        <xsl:value-of select="$Annonce/Lieu" />
    </xsl:template>
    
    <xsl:template match='ensemble'>
        <xsl:value-of select="$Annonce/Ensemble" />
    </xsl:template>
    
    <xsl:template match='listeMusiciens'>
        <xsl:variable name="current-listeMusiciens" select="."/>
        
        <xsl:for-each select="$Annonce/Interprète">
            <xsl:variable name="current-Interprète" select="."/>
            
            <xsl:for-each select="$current-listeMusiciens/p">
                <xsl:copy>
                    <xsl:apply-templates>
                        <xsl:with-param name="interprete" 
                                        select="$current-Interprète" />
                    </xsl:apply-templates>
                </xsl:copy>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template match='musicien'>
        <xsl:param name="interprete"/>
        <xsl:value-of select="$interprete/Nom" />
    </xsl:template>
    
    <xsl:template match='instrument'>
        <xsl:param name="interprete"/>
        <xsl:value-of select="$interprete/Instrument" />
    </xsl:template>
    
    <xsl:template match='listeCompositeurs'> 
        <xsl:value-of select="$Annonce/Compositeurs" />
    </xsl:template>
    
</xsl:stylesheet>
Annonce.html
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>Les Concerts Anacr&eacute;on</title>
   </head>
   <body>
      <H1 align="center"> Concert le Jeudi 17 Janvier 2002 20H30 </H1>
      <H4 align="center"> Chapelle des Ursules </H4>
      <H2 align="center"> Ensemble A deux violes esgales </H2>
      <p>
                         Jonathan Dunford , Basse de viole
      </p>
      <p>
                         Sylvia Abramowicz , Basse de viole
      </p>
      <p>
                         Benjamin Perrot , Th&eacute;orbe
      </p>
      <p>
                         Freddy Eichelberger , Clavecin
      </p>
      <H3> 
                    Oeuvres de 
                M. Marais, D. Castello, F. Rognoni
      </H3>
   </body>
</html>
Conclusion
Measure.tmpl
<?xml version="1.0"?>
<template>
//
//
//-----------------------------------------------------------------------------
// stored Measure <MeasureName/>
//-----------------------------------------------------------------------------
//
    
    protected <MeasureType/> <MeasureName/>;
    
    public final <MeasureType/> get<MeasureNamewithCapital/>() { 
        return <MeasureName/>; 
    }
    
    public final void set<MeasureNamewithCapital/>( 
                                             <MeasureType/> <aMeasureName/> ){
        super.setAttribute("<MeasureName/>", <aMeasureName/>.toString() );
        <MeasureName/> = <aMeasureName/>;
        Assertion.ensure( get<MeasureNamewithCapital/>() == <aMeasureName/> );
    }
    
</template>
Entity.xml
...
<Entity name="Contract" persistance="simple" IHMconnected="true">
    <MeasureRef id="beginningDate" />  
    <MeasureRef id="contractNbr" isPartOfKey="yes" />  
    <MeasureRef id="type" />
</Entity>

<Entity name="Country" persistance="simple" >   
    <MeasureRef id="countryCode" isPartOfKey="yes" />  
    <MeasureRef id="zoneEuro" />
</Entity>
            
<Measure name="contractNbr" type="String" access="stored"  />
<Measure name="type" type="String" access="stored"  />
<Measure name="coefficient" type="String" access="stored"  />
<Measure name="countryCode" type="String" access="stored"  />
<Measure name="zoneEuro" type="Boolean" access="stored"  />
<Measure name="beginningDate" type="BusinessDate" access="stored" />
...

Génération de pages HTML dynamiques pour un portail

fond.xml
<?xml version="1.0" encoding="UTF-16"?>
<html>
    <head>
        <title>Les Concerts Anacréon</title>
    </head>
    <body>
    
        <H1 align="center"> Concert le <dateConcert href="Annonce.xml"/> </H1>
        <H4 align="center"> <lieuConcert href="Annonce.xml"/> </H4>
        <H2 align="center"> Ensemble <ensemble href="Annonce.xml"/> </H2>
        
        <listeMusiciens href="Annonce.xml">
            <p>
                <musicien/>, <instrument/>
            </p>
        </listeMusiciens>
        
        <H3> 
            Oeuvres de <listeCompositeurs href="Annonce.xml"/>
         </H3>
         
         
        <p>
            Réservations : <réservations href="Reservations.xml"/>
        </p>
    
    </body>
</html>
Reservations.xml
<?xml version="1.0" encoding="UTF-16"?>

<Réservations>

    <Réservation>
        <Lieu>Chapelle des Ursules</Lieu>
        <Tel>02 41 11 12 13 14</Tel>
    </Réservation>

    <Réservation>
        <Lieu>Anacréon</Lieu>
        <Tel>02 41 99 97 98 99</Tel>
    </Réservation>

    <Réservation>
        <Lieu>FNAK</Lieu>
        <Tel>02 41 00 97 98 99</Tel>
    </Réservation>
    
</Réservations>
AnnonceConcert.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                version="1.0">

    <xsl:output  method='html' encoding='ISO-8859-1' />
        
    <xsl:template match="child::node()|attribute::*" priority="-10">
        <xsl:copy>
            <xsl:apply-templates select="attribute::*" />
            <xsl:apply-templates select="child::node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match='dateConcert'>
        
        <xsl:variable name="Annonce" select="document(@href)/Annonce"/>
        
        <xsl:value-of select="$Annonce/Date/Jour" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Quantième" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Mois" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Année" />
        <xsl:text> </xsl:text>
        
        <xsl:value-of select="$Annonce/Date/Heure" />
        
    </xsl:template>
    
    <xsl:template match='lieuConcert'>
        <xsl:variable name="Annonce" select="document(@href)/Annonce"/>
        <xsl:value-of select="$Annonce/Lieu" />
    </xsl:template>
    
    <xsl:template match='ensemble'>
        <xsl:variable name="Annonce" select="document(@href)/Annonce"/>
        <xsl:value-of select="$Annonce/Ensemble" />
    </xsl:template>
    
    <xsl:template match='listeMusiciens'>
        <xsl:variable name="Annonce" select="document(@href)/Annonce"/>
        <xsl:variable name="current-listeMusiciens" select="."/>
        
        <xsl:for-each select="$Annonce/Interprète">
            <xsl:variable name="current-Interprète" select="."/>
            
            <xsl:for-each select="$current-listeMusiciens/p">
                <xsl:copy>
                    <xsl:apply-templates>
                        <xsl:with-param name="interprete" 
                                        select="$current-Interprète" />
                    </xsl:apply-templates>
                </xsl:copy>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template match='musicien'>
        <xsl:param name="interprete"/>
        <xsl:value-of select="$interprete/Nom" />
    </xsl:template>
    
    <xsl:template match='instrument'>
        <xsl:param name="interprete"/>
        <xsl:value-of select="$interprete/Instrument" />
    </xsl:template>
    
    <xsl:template match='listeCompositeurs'> 
        <xsl:variable name="Annonce" select="document(@href)/Annonce"/>
        <xsl:value-of select="$Annonce/Compositeurs" />
    </xsl:template>
    
    <xsl:template match='réservations'> 
        <xsl:variable name="réservations" 
                      select="document(@href)/Réservations"/>
        <xsl:for-each select="$réservations/Réservation">
            <br/>
            <xsl:for-each select="*">
                <xsl:value-of select="." />
                <xsl:if test="position() != last()">
                    <xsl:text>, </xsl:text>
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    
</xsl:stylesheet>
AnnonceConcert.html
<html>
    
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>Les Concerts Anacr&eacute;on</title>
   </head>
   <body>
      <H1 align="center"> Concert le Jeudi 17 Janvier 2002 20H30 </H1>
      <H4 align="center"> Chapelle des Ursules </H4>
      <H2 align="center"> Ensemble A deux violes esgales </H2>
      <p>
                         Jonathan Dunford , Basse de viole
      </p>
      <p>
                         Sylvia Abramowicz , Basse de viole
      </p>
      <p>
                         Benjamin Perrot , Th&eacute;orbe
      </p>
      <p>
                         Freddy Eichelberger , Clavecin
      </p>
      <H3> 
                    Oeuvres de 
                M. Marais, D. Castello, F. Rognoni
      </H3>
      <p>
                    R&eacute;servations : <br>Chapelle des Ursules, 02 41 11 12 13 14<br>Anacr&eacute;on, 02 41 99 97 98 99<br>FNAK, 02 41 00 97 98 99
      </p>
   </body>
</html>

Localisation d'une application

Motivation

Réalisation

fond.xml
<?xml version="1.0" encoding="UTF-16"?>
<html>
    <head>
        <title>Les Concerts Anacréon</title>
    </head>
    <body>
    
        <H1 align="center"> <concertLe/> <dateConcert/> </H1>
        <H4 align="center"> <lieuConcert/> </H4>
        <H2 align="center"> <ensemble/> </H2>
        
        <listeMusiciens>
            <p>
                <musicien/>, <instrument/>
            </p>
        </listeMusiciens>
        
        <H3> 
            <oeuvresDe/>
            <listeCompositeurs/>
         </H3>
    
    </body>
</html>
Annonce.xml
<?xml version="1.0" encoding="UTF-16"?>

<Annonce>
    
    <Date>
        <Jour id="jeu"/>
        <Quantième>17</Quantième>
        <Mois id="jnv"/>
        <Année>2002</Année>
        <Heure>20H30</Heure>
    </Date>
    <Lieu>Chapelle des Ursules</Lieu>

    <Ensemble>A deux violes esgales</Ensemble>

    <Interprète>
        <Nom> Jonathan Dunford </Nom>
        <Instrument id="bvl"/>
    </Interprète>

    <Interprète>
        <Nom> Sylvia Abramowicz </Nom>
        <Instrument id="bvl"/>
    </Interprète>

    <Interprète>
        <Nom> Benjamin Perrot </Nom>
        <Instrument id="thb"/>
    </Interprète>

    <Interprète>
        <Nom> Freddy Eichelberger </Nom>
        <Instrument id="clv"/>
    </Interprète>
    
    <Compositeurs>
        M. Marais, D. Castello, F. Rognoni
    </Compositeurs>
    
</Annonce>
Dictionnaire.xml
<?xml version="1.0" encoding="UTF-16"?>

<Dictionnaire>
    <mot id="bvl">
        <traduction lang="fr">Basse de viole</traduction>
        <traduction lang="en">Bass viol</traduction>
    </mot>
    
    <mot id="vdg">
        <traduction lang="fr">Viole de gambe</traduction>
        <traduction lang="en">Viola da gamba</traduction>
    </mot>
    
    <mot id="lth">
        <traduction lang="fr">Luth</traduction>
        <traduction lang="en">Lute</traduction>
    </mot>
    
    <mot id="clv">
        <traduction lang="fr">Clavecin</traduction>
        <traduction lang="en">Harpsichord</traduction>
    </mot>
    
    <mot id="flt">
        <traduction lang="fr">Flûte à bec</traduction>
        <traduction lang="en">Recorder</traduction>
    </mot>
    
    <mot id="thb">
        <traduction lang="fr">Théorbe</traduction>
        <traduction lang="en">Theorbo</traduction>
    </mot>
    
    <mot id="lun">
        <traduction lang="fr">lundi</traduction>
        <traduction lang="en">monday</traduction>
    </mot>
    
    <!-- etc. (les autres jours de la semaine) -->
    
    <mot id="jeu">
        <traduction lang="fr">jeudi</traduction>
        <traduction lang="en">thursday</traduction>
    </mot>
    
    <mot id="jnv">
        <traduction lang="fr">janvier</traduction>
        <traduction lang="en">january</traduction>
    </mot>
    
    <!-- etc. (les autres mois de l'année) -->
    
    <mot id="dcb">
        <traduction lang="fr">décembre</traduction>
        <traduction lang="en">december</traduction>
    </mot>
    
    <mot id="concertLe">
        <traduction lang="fr">Concert le</traduction>
        <traduction lang="en">Concert on</traduction>
    </mot>
    
    <mot id="oeuvresDe">
        <traduction lang="fr">Oeuvres de</traduction>
        <traduction lang="en">Works by</traduction>
    </mot>
    
    <mot id="MarqueQuantième">
        <traduction lang="fr"></traduction>
        <traduction lang="en">th</traduction>
    </mot>
    
</Dictionnaire>
Annonce.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                version="1.0">

    <xsl:output  method='html' encoding='ISO-8859-1' />
    
    <xsl:param name="langueCible">fr</xsl:param>
    <xsl:param name="dicoFileRef">dictionnaire.xml</xsl:param>
    <xsl:param name="annonceFileRef">Annonce.xml</xsl:param>
    
    <xsl:variable name="Dictionnaire" 
                  select="document($dicoFileRef)/Dictionnaire"/>
    <xsl:variable name="Annonce" 
                  select="document($annonceFileRef)/Annonce"/>
        
    <xsl:template name="instancier-traduction">
        <xsl:param name="motId"/>
        
        <xsl:variable 
            name="motTrouvé" 
            select="$Dictionnaire/mot[@id=$motId]" />
            
        <xsl:variable 
            name="saTraduction" 
            select="$motTrouvé/traduction[@lang=$langueCible]" />
            
        <xsl:value-of select="$saTraduction" />
    </xsl:template>
    
    <xsl:template match="child::node()|attribute::*" priority="-10">
        <xsl:copy>
            <xsl:apply-templates select="attribute::*" />
            <xsl:apply-templates select="child::node()"/>
        </xsl:copy>
    </xsl:template> 
    
    <xsl:template match='concertLe'> 
        <xsl:call-template name="instancier-traduction">
            <xsl:with-param name="motId" select="'concertLe'" />
        </xsl:call-template> 
        <xsl:text> </xsl:text>
    </xsl:template>
    
    <xsl:template name='instancier-Date'>
    
        <xsl:param name="Jour"/>
        <xsl:param name="Quantième"/>
        <xsl:param name="Mois"/>
        <xsl:param name="Année"/>
        
        <xsl:choose>
            <xsl:when test="$langueCible = 'fr'">
                <xsl:value-of select="$Jour"/>
                <xsl:text> </xsl:text>
                <xsl:value-of select="$Quantième"/>
                <xsl:text> </xsl:text>
                <xsl:value-of select="$Mois"/>
                <xsl:text> </xsl:text>
                <xsl:value-of select="$Année"/>
            </xsl:when>
            
            <xsl:when test="$langueCible = 'en'">
                <xsl:value-of select="$Jour"/>
                <xsl:text>, the </xsl:text>
                <xsl:value-of select="$Quantième"/>
                <xsl:text>th of </xsl:text>
                <xsl:value-of select="$Mois"/>
                <xsl:text>, </xsl:text>
                <xsl:value-of select="$Année"/>
            </xsl:when>
        </xsl:choose>
    
        
    </xsl:template>
    
    
    <xsl:template match='dateConcert'>
        
         <xsl:call-template name="instancier-Date">
        
            <xsl:with-param name="Jour"> 
                <xsl:call-template name="instancier-traduction">
                    <xsl:with-param name="motId" 
                                    select="$Annonce/Date/Jour/@id" />
                </xsl:call-template> 
            </xsl:with-param>
            
            <xsl:with-param name="Quantième">
                <xsl:value-of select="$Annonce/Date/Quantième" />
            </xsl:with-param>
            
            <xsl:with-param name="Mois">
                <xsl:call-template name="instancier-traduction">
                    <xsl:with-param name="motId" 
                                    select="$Annonce/Date/Mois/@id" />
                </xsl:call-template> 
            </xsl:with-param>
            
            <xsl:with-param name="Année">
                <xsl:value-of select="$Annonce/Date/Année" />
            </xsl:with-param>
            
        </xsl:call-template>
        
        <xsl:text> </xsl:text>
        <xsl:value-of select="$Annonce/Date/Heure" />

        
    </xsl:template>
    
    <xsl:template match='lieuConcert'>
        <xsl:value-of select="$Annonce/Lieu" />
    </xsl:template>
    
    <xsl:template match='ensemble'>
        <xsl:value-of select="$Annonce/Ensemble" />
    </xsl:template>
    
    <xsl:template match='listeMusiciens'>
        <xsl:variable name="current-listeMusiciens" select="."/>
        
        <xsl:for-each select="$Annonce/Interprète">
            <xsl:variable name="current-Interprète" select="."/>
            
            <xsl:for-each select="$current-listeMusiciens/p">
                <xsl:copy>
                    <xsl:apply-templates>
                        <xsl:with-param name="interprete" 
                                        select="$current-Interprète" />
                    </xsl:apply-templates>
                </xsl:copy>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template match='musicien'>
        <xsl:param name="interprete"/>
        <xsl:value-of select="$interprete" />
    </xsl:template>
    
    <xsl:template match='instrument'>
        <xsl:param name="interprete"/>
        <xsl:text> </xsl:text>
        
        <xsl:call-template name="instancier-traduction">
            <xsl:with-param name="motId" select="$interprete/Instrument/@id" />
        </xsl:call-template> 
    </xsl:template>
     
    
    <xsl:template match='oeuvresDe'> 
        <xsl:call-template name="instancier-traduction">
            <xsl:with-param name="motId" select="'oeuvresDe'" />
        </xsl:call-template> 
        <xsl:text> </xsl:text>
    </xsl:template>
    
    <xsl:template match='listeCompositeurs'> 
        <xsl:value-of select="$Annonce/Compositeurs" />
    </xsl:template>
    
</xsl:stylesheet>

Construction dynamique de l'agencement d'un tableau HTML

Version statique

baseProduits.xml
<?xml version="1.0" encoding="UTF-16" ?>
<BaseProduits>

    <LesProduits>
    
        <Livre ref="vernes1" NoISBN="193335" gamme="roman" media="papier">
            <refOeuvres>
                <Ref valeur="20000lslm"/>
            </refOeuvres>
            <Prix valeur="6" monnaie="EUR"/>
            <Prix valeur="5" monnaie="£"/>
        </Livre>
    
        <Livre ref="boileaunarcejac1" NoISBN="533791" gamme="roman" 
                                                      media="papier">
            <refOeuvres>
                <Ref valeur="liatlc.bn"/>
            </refOeuvres>
            <Prix valeur="4.5" monnaie="EUR"/>
            <Prix valeur="3" monnaie="£"/>
        </Livre>
    
        <Enregistrement ref="marais1" RefEditeur="LC000280" 
                                               gamme="violedegambe" media="CD">
            <refOeuvres>
                <Ref valeur="marais.folies"/>
                <Ref valeur="marais.pieces1685"/>
            </refOeuvres>
            <Interprètes>
                <Interprète nom="Jonathan Dunford">
                    <Role xml:lang="fr"> Basse de viole </Role>
                    <Role xml:lang="en"> Bass Viol </Role>
                </Interprète>
                <Interprète nom="Sylvia Abramowicz">
                    <Role xml:lang="fr"> Basse de viole </Role>
                    <Role xml:lang="en"> Bass Viol </Role>
                </Interprète>
                <Interprète nom="Benjamin Perrot">
                    <Role xml:lang="fr"> Théorbe et guitare baroque </Role>
                    <Role xml:lang="en"> Theorbo and baroque guitar </Role>
                </Interprète>
                <Interprète nom="Stéphane Fuget">
                    <Role xml:lang="fr"> Clavecin </Role>
                    <Role xml:lang="en"> Harpsichord </Role>
                </Interprète>
            </Interprètes>
            <Titre xml:lang="fr">
                Les Folies d'Espagne et pièces inédites
            </Titre>
            <Titre xml:lang="en"> Folies d'Espagne and unedited music </Titre>
            <Prix valeur="21" monnaie="EUR"/>
            <Prix valeur="13" monnaie="£"/>
        </Enregistrement>
    
        <Matériel ref="HarKar1" refConstructeur="XL-FZ158BK" gamme="lecteurCD" 
                                                              marque="HarKar">
            <refCaractéristiques>
                <Ref valeur="caracHarKar1"/>
            </refCaractéristiques>
            <Prix valeur="686" monnaie="EUR"/>
            <Prix valeur="400" monnaie="£"/>
        </Matériel>
        
    </LesProduits>
    
    <LesOeuvres>
        <Oeuvre ref="20000lslm">
            <Titre> Vingt mille lieues sous les mers </Titre>
            <refAuteurs>
                <Ref valeur="JVernes"/>
            </refAuteurs>
        </Oeuvre>
        <Oeuvre ref="marais.folies">
            <Titre> Les Folies d'Espagne </Titre>
            <refAuteurs>
                <Ref valeur="MMarais"/>
            </refAuteurs>
        </Oeuvre>
        <Oeuvre ref="marais.pieces1685">
            <Titre> Pièces de viole en manuscrit </Titre>
            <refAuteurs>
                <Ref valeur="MMarais"/>
            </refAuteurs>
        </Oeuvre>
        <Oeuvre ref="liatlc.bn">
            <Titre> L'ingénieur aimait trop les chiffres </Titre>
            <refAuteurs>
                <Ref valeur="PBoileau"/>
                <Ref valeur="ThNarcejac"/>
            </refAuteurs>
        </Oeuvre>
    </LesOeuvres>
    
    <LesAuteurs>
        <Auteur ref="JVernes">
            <Nom> Jules Vernes </Nom>
        </Auteur>
        <Auteur ref="MMarais">
            <Nom> Marin Marais </Nom>
        </Auteur>
        <Auteur ref="PBoileau">
            <Nom> Pierre Boileau </Nom>
        </Auteur>
        <Auteur ref="ThNarcejac">
            <Nom> Thomas Narcejac </Nom>
        </Auteur>
    </LesAuteurs>
    
    <LesGammes>
        ... inutilisé ici ...
    </LesGammes>
    
    <LesMarques>
        ... inutilisé ici ...
    </LesMarques>
    
    <LesCaractéristiques>
        ... inutilisé ici ...
    </LesCaractéristiques>
    
</BaseProduits>
baseProduits.xsl
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">


    <xsl:template match="/">
    <HTML>
        <HEAD>
            <TITLE>Catalogue</TITLE>
        </HEAD>
        <BODY>
            <xsl:apply-templates/>
        </BODY>
    </HTML>
    </xsl:template>
    
    <xsl:template match="LesProduits">
        <table border="1"> 
            <tr>
                <th>Produit</th>
                <th>ISBN</th>
                <th>Prix</th>
                <th>Titre</th>
                <th>Auteur</th>
                <th>Interprète</th>
            </tr> 
            <xsl:apply-templates/> 
        </table>
    </xsl:template>
    
    <xsl:template match="Livre">
        <tr>
            <td>Livre</td>
            <td><xsl:value-of select="@NoISBN"/></td>
            <td><xsl:value-of select="./Prix[@monnaie='EUR']/@valeur"/></td>
            <td>
                <xsl:call-template name="instancier-titreOeuvre">
                    <xsl:with-param name="refOeuvre" 
                                    select="./refOeuvres/Ref[1]/@valeur" />
                </xsl:call-template>
            </td>
            <td>
                <xsl:call-template name="instancier-nomsAuteurs">
                    <xsl:with-param name="refOeuvre" 
                                    select="./refOeuvres/Ref[1]/@valeur" />
                </xsl:call-template>
            </td>
            <td><xsl:call-template name="instancier-nbsp"/></td>
        </tr> 
    </xsl:template>
    
    <xsl:template match="Enregistrement">
        <tr>
            <td>Disque Compact</td>
            <td><xsl:call-template name="instancier-nbsp"/></td>
            <td><xsl:value-of select="./Prix[@monnaie='EUR']/@valeur"/></td>
            <td>
                <xsl:call-template name="instancier-titreOeuvre">
                    <xsl:with-param name="refOeuvre" 
                                    select="./refOeuvres/Ref[1]/@valeur" />
                </xsl:call-template>
            </td>
            <td>
                <xsl:call-template name="instancier-nomsAuteurs">
                    <xsl:with-param name="refOeuvre" 
                                    select="./refOeuvres/Ref[1]/@valeur" />
                </xsl:call-template>
            </td>
            <td>
                <xsl:call-template name="instancier-interprètes"/>
            </td>
        </tr> 
    </xsl:template>
    
    <xsl:template match="text()"/>
    
    <xsl:template name="instancier-titreOeuvre">
        <xsl:param name="refOeuvre"/>
        <xsl:variable name="Oeuvre" 
                      select="//LesOeuvres/Oeuvre[@ref=$refOeuvre]"/>
        <xsl:value-of select="$Oeuvre/Titre"/>
    </xsl:template>
    
    <xsl:template name="instancier-nomsAuteurs">
        <xsl:param name="refOeuvre"/>
        <xsl:variable name="Oeuvre" 
                      select="//LesOeuvres/Oeuvre[@ref=$refOeuvre]"/>
        <xsl:for-each select="$Oeuvre/refAuteurs/Ref">
            <xsl:variable name="refAuteur" select="@valeur"/>
            <xsl:variable name="Auteur" 
                          select="//LesAuteurs/Auteur[@ref=$refAuteur]"/>
        
            <xsl:value-of select="$Auteur/Nom"/>
            <xsl:if test="position() != last()"><br/></xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template name="instancier-interprètes">
        <xsl:for-each select="Interprètes/Interprète">
            <xsl:value-of select="@nom"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="Role[@xml:lang = 'fr']"/>
            <xsl:if test="position() != last()"><br/></xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template name="instancier-nbsp">
        <xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
    </xsl:template>
    
</xsl:stylesheet>

Version dynamique

Table.xml
<?xml version="1.0" encoding="UTF-16" ?>
<table id="LivresEtEnregistrements">

    <colonne titre="Produit">
        <Livre
            valeur="Livre"/>
        <Enregistrement 
            valeur="Compact Disc"/>
    </colonne>
    
    <colonne titre="Prix">
        <Livre 
            eval="./Prix[@monnaie='EUR']/@valeur"/>
        <Enregistrement 
            eval="./Prix[@monnaie='EUR']/@valeur"/>
    </colonne> 
    
    <colonne titre="ISBN">
        <Livre 
            eval="./@NoISBN"/>
        <Enregistrement 
            call="instancier-nbsp"/>
    </colonne>
    
    <colonne titre="Auteur">
        <Livre 
             call="instancier-nomsAuteurs" 
             param="./refOeuvres/Ref[1]/@valeur"/>
        <Enregistrement 
            call="instancier-nomsAuteurs" 
            param="./refOeuvres/Ref[1]/@valeur"/>
    </colonne>  
                                          
    <colonne titre="Titre">
        <Livre 
            call="instancier-titreOeuvre" 
            param="./refOeuvres/Ref[1]/@valeur"/>
        <Enregistrement 
            call="instancier-titreOeuvre" 
            param="./refOeuvres/Ref[1]/@valeur"/>
    </colonne>
    
    <colonne titre="Interprète">
        <Livre 
             call="instancier-nbsp"/>
        <Enregistrement 
            call="instancier-interprètes"/>
    </colonne>
</table>

Pattern

$ElementCourant/./Prix[@monnaie='EUR']/@valeur
'$ElementCourant'
'/'
./Prix[@monnaie='EUR']/@valeur
concat('$ElementCourant', '/', @eval)
$ElementCourant/./Prix[@monnaie='EUR']/@valeur
saxon:evaluate(
    concat('$ElementCourant', '/', @eval)
)
<Livre 
    call="instancier-nomsAuteurs" 
    param="./refOeuvres/Ref[1]/@valeur"/>
'$ElementCourant'
'/'
./refOeuvres/Ref[1]/@valeur
concat('$ElementCourant', '/', @param)
$ElementCourant/./refOeuvres/Ref[1]/@valeur
<xsl:call-template name="{$tname}" saxon:allow-avt="yes">
baseProduits.xsl
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet 
    xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" 
    xmlns:saxon="http://icl.com/saxon"
    extension-element-prefixes="saxon"
    version   = "1.0">

    <xsl:output  method='html' encoding='ISO-8859-1' />
    
    <xsl:variable 
        name="tableLivresEtEnregistrements" 
        select="document('Table.xml')/table[@id='LivresEtEnregistrements']"/>
        
    <xsl:variable 
        name="racineDocumentPrincipal" 
        select="/"/>

    <xsl:template match="/">
        <HTML>
            <HEAD>
                <TITLE>Catalogue</TITLE>
            </HEAD>
            <BODY>
                <xsl:apply-templates/>
            </BODY>
        </HTML>
    </xsl:template>
    
    <xsl:template match="LesProduits">
        <table border="1" > 
            <tr>
                <xsl:call-template name="instancier-titresColonnes"/>
            </tr> 
            <xsl:apply-templates/> 
        </table>
    </xsl:template>
    
    
    <!--
    ====================================================== 
                           Etape 1 
    ====================================================== -->
    <xsl:template match="Livre">
        <tr>
            <xsl:call-template name="instancier-colonnes"/>
        </tr> 
    </xsl:template>
    
    <!--
    ====================================================== 
                           Etape 1 
    ====================================================== -->
    <xsl:template match="Enregistrement">
        <tr>
            <xsl:call-template name="instancier-colonnes"/>
        </tr> 
    </xsl:template>
    
    <!--
    ======================================================  -->
    
    <xsl:template match="text()"/>
    
    
    
    <!--
    ====================================================== 
                           Fin des règles 
    ====================================================== -->
    
    <xsl:template name="instancier-titresColonnes">
        <xsl:for-each select="$tableLivresEtEnregistrements/colonne">
            <th><xsl:value-of select="@titre"/></th>
        </xsl:for-each>
    </xsl:template>
    
    <!-- -->
    
    <xsl:template name="instancier-colonnes">
    
        <!-- 
        Comme ce modèle est appelé depuis une règle sans xsl:for-each,
        l'élément courant est l'élément traité par la règle, à savoir
        un <Livre> ou un <Enregistrement>
         -->
        <xsl:variable name="ElementCourant" select="current()"/>
        <xsl:variable name="ElementName" select="local-name()"/>
        
        
    
        <!--
        ====================================================== 
                               Etape 2 
        ====================================================== -->
        <xsl:variable 
            name="ElementsPilotes" 
            select="saxon:evaluate(
                        concat( 
                            '$tableLivresEtEnregistrements/colonne/',
                            $ElementName 
                        )
                    )"
        />
        
        
        <!-- 
        
        Valeur de la variable $ElementsPilotes dans notre exemple :
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        cas où $ElementCourant est un <Livre>
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            <Livre valeur="Livre"></Livre>
            <Livre eval="./Prix[@monnaie='EUR']/@valeur"></Livre>
            <Livre eval="./@NoISBN"></Livre>
            
            <Livre call="instancier-nomsAuteurs" 
                   param="./refOeuvres/Ref[1]/@valeur"></Livre>
            
            <Livre call="instancier-titreOeuvre" 
                   param="./refOeuvres/Ref[1]/@valeur"></Livre>
            
            <Livre call="instancier-nbsp"></Livre>
         
         
        cas où $ElementCourant est un <Enregistrement>
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            <Enregistrement valeur="Compact Disc"></Enregistrement>
            <Enregistrement eval="./Prix[@monnaie='EUR']/@valeur">
            </Enregistrement>
            <Enregistrement call="instancier-nbsp"></Enregistrement>
            
            <Enregistrement call="instancier-nomsAuteurs" 
                            param="./refOeuvres/Ref[1]/@valeur">
            </Enregistrement>
            
            <Enregistrement call="instancier-titreOeuvre" 
                            param="./refOeuvres/Ref[1]/@valeur">
            </Enregistrement>
            
            <Enregistrement call="instancier-interprètes">
            </Enregistrement>   
            
         -->
        
        
        
        <!--
        ====================================================== 
                               Etape 3 
        ====================================================== -->
        
        <xsl:for-each select="$ElementsPilotes">
            <td>
                <xsl:choose>
                
        
                    <!--
                    ====================================================== 
                                           Etape 3A 
                    ====================================================== -->
                    <xsl:when test="@valeur">
                        <xsl:value-of select="@valeur"/>
                    </xsl:when>
                
                    <!--
                    ====================================================== 
                                           Etape 3B 
                    ====================================================== -->
                    <xsl:when test="@eval">
                        <xsl:value-of select="saxon:evaluate(
                            concat('$ElementCourant', '/', @eval)
                        )"/>
                    </xsl:when>
                    
                
                    <!--
                    ====================================================== 
                                           Etape 3C 
                    ====================================================== -->
                    <xsl:when test="@call">
                        
                        <xsl:choose>
                            <xsl:when test="@param">
                                <xsl:call-template 
                                    name="{@call}" saxon:allow-avt="yes">
                                    <xsl:with-param 
                                        name="refOeuvre" 
                                        select="saxon:evaluate(
                                                    concat('$ElementCourant',
                                                                   '/', @param)
                                                )"/>
                                </xsl:call-template>
                            </xsl:when>
                            
                            <xsl:otherwise>
                                <xsl:call-template 
                                    name="{@call}" saxon:allow-avt="yes">
                                    <xsl:with-param 
                                        name="ElementCourant" 
                                        select="$ElementCourant"/>
                                </xsl:call-template>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                
                </xsl:choose>
            </td>
        </xsl:for-each>
    </xsl:template>
    
    
    <!-- -->
    <xsl:template name="instancier-titreOeuvre">
        <xsl:param name="refOeuvre"/>
        <xsl:variable 
            name="Oeuvre" 
            select="
                $racineDocumentPrincipal//LesOeuvres/Oeuvre[@ref=$refOeuvre]"/>
        <xsl:value-of select="$Oeuvre/Titre"/>
    </xsl:template>
    
    
    <!-- -->
    <xsl:template name="instancier-nomsAuteurs">
        <xsl:param name="refOeuvre"/>
        <xsl:variable 
            name="Oeuvre" 
            select="
                $racineDocumentPrincipal//LesOeuvres/Oeuvre[@ref=$refOeuvre]"/>
        <xsl:for-each select="$Oeuvre/refAuteurs/Ref">
            <xsl:variable name="refAuteur" select="@valeur"/>
            <xsl:variable 
                name="Auteur" 
                select="//LesAuteurs/Auteur[@ref=$refAuteur]"/>
            <xsl:value-of select="$Auteur/Nom"/>
            <xsl:if test="position() != last()"><br/></xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    
    <!-- -->
    <xsl:template name="instancier-interprètes">
        <xsl:param name="ElementCourant"/>
        <xsl:for-each select="$ElementCourant/Interprètes/Interprète">
            <xsl:value-of select="@nom"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="Role[@xml:lang = 'fr']"/>
            <xsl:if test="position() != last()"><br/></xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    
    <!-- -->
    <xsl:template name="instancier-nbsp">
        <xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
    </xsl:template>
    
</xsl:stylesheet>
Ligne de commande (d'un seul tenant)
java -classpath "C:\Program Files\JavaSoft\SAXON\saxon.jar;" com.icl.saxon.StyleSheet -o baseProduits.html BaseProduits.xml BaseProduits.xsl ordreColonnes="Produit Prix Auteur Titre ISBN Interprète"
baseProduits.xsl
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet 
    xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" 
    xmlns:saxon="http://icl.com/saxon"
    extension-element-prefixes="saxon"
    version   = "1.0">

    <xsl:output  method='html' encoding='ISO-8859-1' />

    <xsl:param 
        name="ordreColonnes" 
        select="'Produit Prix Auteur Titre ISBN Interprète'"/>  
        <!-- donne l'ordre par défaut des colonnes -->
    
    <xsl:variable 
        name="tableLivresEtEnregistrements" 
        select="document('Tables.xml')/table[@id='LivresEtEnregistrements']"/>
        
    <xsl:variable 
        name="racineDocumentPrincipal" 
        select="/"/>

    <xsl:template match="/">
        <HTML>
            <HEAD>
                <TITLE>Catalogue</TITLE>
            </HEAD>
            <BODY>
                <xsl:apply-templates/>
            </BODY>
        </HTML>
    </xsl:template>
    
    <xsl:template match="LesProduits">
        <table border="1" > 
            <tr>
                <xsl:call-template name="instancier-titresColonnes"/>
            </tr> 
            <xsl:apply-templates/> 
        </table>
    </xsl:template>
    
    <!--
    ====================================================== 
                           Etape 1 
    ====================================================== -->
    <xsl:template match="Livre">
        <tr>
            <xsl:call-template name="instancier-colonnes"/>
        </tr> 
    </xsl:template>
    <!--
    ====================================================== 
                           Etape 1 
    ====================================================== -->
    <xsl:template match="Enregistrement">
        <tr>
            <xsl:call-template name="instancier-colonnes"/>
        </tr> 
    </xsl:template>
    
    <!--
    ======================================================  -->
    
    <xsl:template match="text()"/>
    
    
    
    <!--
    ====================================================== 
                           Fin des règles 
    ====================================================== -->
    
    <xsl:template name="instancier-titresColonnes">
        <xsl:for-each select="saxon:tokenize( $ordreColonnes )">
            <th><xsl:value-of select="."/></th>
        </xsl:for-each>
    </xsl:template>
    
    <!-- -->
    <xsl:template name="instancier-colonnes">
    
        <!-- 
        Comme ce modèle est appelé depuis une règle sans xsl:for-each,
        l'élément courant est l'élément traité par la règle, à savoir
        un <Livre> ou un <Enregistrement>
        -->
        <xsl:variable name="ElementCourant" select="current()"/>
        <xsl:variable name="ElementName" select="local-name()"/>
        
        <!--
        ====================================================== 
                               Etape 3 
        ====================================================== -->
        <xsl:variable 
            name="LesNomsDeColonnes" 
            select="saxon:tokenize( $ordreColonnes )"/>
        
        <xsl:for-each select="$LesNomsDeColonnes">
        
        
            <xsl:variable 
                name="NomDeLaColonneEnCours" 
                select="."/>
            
            <xsl:variable 
                name="ElementPilote" 
                select="saxon:evaluate(
                            concat( 
                                '$tableLivresEtEnregistrements/colonne[
                                    @titre=&#34;', 
                                    $NomDeLaColonneEnCours, '&#34;]/',
                                $ElementName 
                            )
                        )"
            />
            <xsl:for-each select="$ElementPilote">
        
            <td>
                <xsl:choose>
                
                    <!--
                    ====================================================== 
                                           Etape 3A 
                    ====================================================== -->
                    <xsl:when test="@valeur">
                        <xsl:value-of select="@valeur"/>
                    </xsl:when>
                
                    <!--
                    ====================================================== 
                                           Etape 3B 
                    ====================================================== -->
                    <xsl:when test="@eval">
                        <xsl:value-of select="saxon:evaluate(
                            concat('$ElementCourant', '/', @eval)
                        )"/>
                    </xsl:when>
                    
                    <!--
                    ====================================================== 
                                           Etape 3C 
                    ====================================================== -->
                    <xsl:when test="@call">
                        
                        <xsl:choose>
                            <xsl:when test="@param">
                                <xsl:call-template 
                                    name="{@call}" saxon:allow-avt="yes">
                                    <xsl:with-param 
                                        name="refOeuvre" 
                                        select="saxon:evaluate(
                                          concat('$ElementCourant','/', @param)
                                        )"/>
                                </xsl:call-template>
                            </xsl:when>
                            
                            <xsl:otherwise>
                                <xsl:call-template 
                                    name="{@call}" saxon:allow-avt="yes">
                                    <xsl:with-param 
                                        name="ElementCourant" 
                                        select="$ElementCourant"/>
                                </xsl:call-template>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                
                </xsl:choose>
            </td>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    
    <!-- -->
    <xsl:template name="instancier-titreOeuvre">
        <xsl:param name="refOeuvre"/>
        <xsl:variable 
            name="Oeuvre" 
            select="
                $racineDocumentPrincipal//LesOeuvres/Oeuvre[@ref=$refOeuvre]"/>
        <xsl:value-of select="$Oeuvre/Titre"/>
    </xsl:template>
    
    <!-- -->
    <xsl:template name="instancier-nomsAuteurs">
        <xsl:param name="refOeuvre"/>
        <xsl:variable 
            name="Oeuvre" 
            select="
                $racineDocumentPrincipal//LesOeuvres/Oeuvre[@ref=$refOeuvre]"/>
        <xsl:for-each select="$Oeuvre/refAuteurs/Ref">
            <xsl:variable name="refAuteur" select="@valeur"/>
            <xsl:variable 
                name="Auteur" 
                select="//LesAuteurs/Auteur[@ref=$refAuteur]"/>
            <xsl:value-of select="$Auteur/Nom"/>
            <xsl:if test="position() != last()"><br/></xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    <!-- -->
    <xsl:template name="instancier-interprètes">
        <xsl:param name="ElementCourant"/>
        <xsl:for-each select="$ElementCourant/Interprètes/Interprète">
            <xsl:value-of select="@nom"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="Role[@xml:lang = 'fr']"/>
            <xsl:if test="position() != last()"><br/></xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    <!-- -->
    <xsl:template name="instancier-nbsp">
        <xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
    </xsl:template>
    
</xsl:stylesheet>
$tableLivresEtEnregistrements/colonne[@titre="Prix"]/Livre

Génération de documents multiples

XMLXSL.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<presentation titre="Cours XML">

    
    <pageDeTitre id="XML.0" nextPage="XML.1">
        <titrePresentation>Comprendre XML et XSL</titrePresentation>
        <credit>
            <groupeAuteurs>
                <auteur>Philippe Drix</auteur>
                <societe>OBJECTIVA</societe>
            </groupeAuteurs>
        </credit>
    </pageDeTitre>
        
    
    <pageStandard id="XML.1" previousPage="XML.0" nextPage="Table">
        <titre1 id="XML.1.Deroulement">Déroulement du Cours</titre1>
        <bloc1>
            <item>
            Le cours XML se déroule de 9h30 à 12h30 et de 14h à 17h30.
            </item>
            <bloc2>
                <item>
                Pauses-café à 11h et 16h.
                </item>
                <item>
                Discussions libres pendant le déjeuner et après 17h30.
                </item>
            </bloc2>
        </bloc1>
        <bloc1>
            <item>
            Le dernier jour, foire aux questions de 16h30 à 17h30.
            </item>
        </bloc1>
    </pageStandard>
    
    <plan id="Table" previousPage="XML.1" nextPage="XML.2"/>
        
    <pageStandard id="XML.2" previousPage="Table">
        <titre1 id="XML.2general"> XML - Généralités </titre1>
        <bloc1>
            <item>
            XML est un langage de balisage de textes.
            </item>
        </bloc1>
        <titre2 id="XML.2.balisage"> Balisage </titre2>
        <bloc1>
            <item>
            Le principe d'un langage de balisage de textes existe depuis 
            fort longtemps, 
            avant même l'invention de l'informatique.
            </item>
            <bloc2>
                <item>
                en imprimerie, le texte de l'épreuve est balisée de 
                "corrections" à effectuer (balises textuelles),
                </item>
                <item>
                et les relectures à voix haute, chez les typographes, 
                se font agrémentées de balises vocales codifiées, avec tout un 
                argot de métier assez savoureux (trouvé dans "Petite Histoire 
                des signes de corrections typographiques", par Jacques André, 
                in Cahier GUTemberg No 31, Décembre 1998) :
                </item>
                <bloc3>
                    <item>
                    le métro (inventé par Bienvenüe ! ...)
                    </item>
                    <item>
                    le métro <texteImportant>ouvre</texteImportant> inventé 
                    par Bienvenüe <texteImportant>cap couilles clame suce ferme
                    </texteImportant>
                    </item>
                </bloc3>
            </bloc2>
        </bloc1>
        <bloc1>
            <item>
            Avec l'invention de l'informatique, les techniques de balisages 
            se sont appliquées à la commande des Linotypes par bandes 
            perforées, où le texte à composer était parsemé de commandes 
            destinées à la manoeuvre de la Lynotype elle même (passer en gras, 
            changer de corps, faire un retrait, etc.).
            </item>
        </bloc1>
    </pageStandard>
    
</presentation>
<xsl:template name="instancier-page">

    <xsl:param name="fileName"/>
    <xsl:param name="next"/>
    <xsl:param name="prev"/>
    
    <xsl:document href="{$fileName}">
        <xsl:call-template name="instancier-entête">
            <xsl:with-param name="next" select="concat( $next, '.html')" />
            <xsl:with-param name="prev" select="concat( $prev, '.html')" />
        </xsl:call-template>
            
        <TABLE width="100%" height="90%" BORDER="0" CELLSPACING="10">
        <TR valign="top"><TD>
            <xsl:apply-templates/>
        </TD></TR>
        </TABLE>
        
        <xsl:call-template name="instancier-piedDePage"/>
    </xsl:document>
    
</xsl:template>
XMLXSL.xsl
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.1"> <!-- compatibilité Saxon 6.5 -->

    <xsl:output  method='html' encoding='ISO-8859-1' />
    
    
    <!-- 
    ====================================================== -->
    <xsl:template match="pageDeTitre">
        <xsl:call-template name="instancier-page">
            <xsl:with-param name="fileName" select="concat( @id, '.html' )" />
            <xsl:with-param name="next" select="@nextPage" />
        </xsl:call-template>    
    </xsl:template>
    
    <xsl:template match="titrePresentation">
        <H1 align="center"><xsl:value-of select="."/></H1>
    </xsl:template>
    
    <xsl:template match="auteur">
        <H2 align="center"><xsl:value-of select="."/></H2>
    </xsl:template>
    
    <xsl:template match="societe">
        <H2 align="center"><xsl:value-of select="."/></H2>
    </xsl:template>
    
    <!-- 
    ====================================================== -->
    
    <xsl:template match="pageStandard">
        <xsl:call-template name="instancier-page">
            <xsl:with-param name="fileName" select="concat( @id, '.html' )" />
            <xsl:with-param name="prev" select="@previousPage" />
            <xsl:with-param name="next" select="@nextPage" />
        </xsl:call-template>    
    </xsl:template>
    
    <xsl:template match="titre1">
        <H1 align="left"><xsl:value-of select="."/></H1>
    </xsl:template>
    
    <xsl:template match="titre2">
        <H2 align="left"><xsl:value-of select="."/></H2>
    </xsl:template>
    
    <xsl:template match="bloc1">
        <UL TYPE="SQUARE"><xsl:apply-templates/></UL>
    </xsl:template>
    
    <xsl:template match="item">
        <LI><xsl:apply-templates/></LI>
    </xsl:template>
    
    <xsl:template match="bloc2">
        <UL TYPE="CIRCLE"><xsl:apply-templates/></UL>
    </xsl:template>
    
    <xsl:template match="bloc3">
        <UL TYPE="DISC"><xsl:apply-templates/></UL>
    </xsl:template>
    
    <xsl:template match="texteImportant">
        <B><xsl:apply-templates/></B>
    </xsl:template>
    
    <!-- 
    ====================================================== -->
    <xsl:template match="plan">
        <xsl:call-template name="instancier-plan">
            <xsl:with-param name="fileName" select="concat( @id, '.html' )" />
            <xsl:with-param name="prev" select="@previousPage" />
            <xsl:with-param name="next" select="@nextPage" />
        </xsl:call-template>    
    </xsl:template>
    
    
    <xsl:template match="titre1" mode="plan">
        <H1 align="left">
        <A HREF="{concat(parent::*/@id, '.html')}">
        <xsl:value-of select="."/>
        </A>
        </H1>
    </xsl:template>
    
    <xsl:template match="titre2" mode="plan">
        <H2 align="left">
        <A HREF="{concat(parent::*/@id, '.html')}">
        <xsl:value-of select="."/>
        </A>
        </H2>
    </xsl:template>
    
    <xsl:template match="text()" mode="plan"/>
    
    <!-- 
    ====================================================== -->
        
    <!--   -->
    <xsl:template name="instancier-page">
    
        <xsl:param name="fileName"/>
        <xsl:param name="next"/>
        <xsl:param name="prev"/>
        
        <xsl:document href="{$fileName}">
        <HTML>
            <HEAD>
                <TITLE>Cours XML</TITLE>
            </HEAD>
            <BODY>
            <xsl:call-template name="instancier-entête">
                <xsl:with-param name="next" select="concat( $next, '.html')" />
                <xsl:with-param name="prev" select="concat( $prev, '.html')" />
            </xsl:call-template>
                
            <TABLE width="100%" height="90%" BORDER="0" CELLSPACING="10">
            <TR valign="top"><TD>
                <xsl:apply-templates/>
            </TD></TR>
            </TABLE>
            
            <xsl:call-template name="instancier-piedDePage"/>
            </BODY>
        </HTML>
        </xsl:document>
        
    </xsl:template>
    
    <!--   -->
    <xsl:template name="instancier-entête">
    
        <xsl:param name="next"/>
        <xsl:param name="prev"/>
            
        <TABLE valign="top" width="100%" height="2%" BORDER="0" CELLSPACING="0"
                                                             BGCOLOR="#FFFF99">
            <TR>
            <TD width="33%" align="left">
            <A HREF="{$prev}">Page précédente</A>
            </TD>
            <TD width="34%" align="center">
            <A HREF="Table.html">Table</A>
            </TD>
            <TD width="33%" align="right">
            <A HREF="{$next}">Page suivante</A>
            </TD>
            </TR>
        </TABLE>
    </xsl:template>
    
    
    
    <!--   -->
    <xsl:template name="instancier-piedDePage">
    
        <xsl:param name="next"/>
        <xsl:param name="prev"/>
            
        <TABLE valign="top" width="100%" height="2%" BORDER="0" CELLSPACING="0"
                                                             BGCOLOR="#FFFF99">
            <TR>
            <TD width="33%" align="left">Ph. Drix - Objectiva</TD>
            <TD width="34%" align="center">Comprendre XML et XSL</TD>
            <TD width="33%" align="right">
            <xsl:number count="pageDeTitre | pageStandard | plan" level="any"/>
            </TD>
            </TR>
        </TABLE>
    </xsl:template>
    
    
        
    <!--   -->
    <xsl:template name="instancier-plan">
    
        <xsl:param name="fileName"/>
        <xsl:param name="next"/>
        <xsl:param name="prev"/>
        
        <xsl:document href="{$fileName}">
        <HTML>
            <HEAD>
                <TITLE>Cours XML</TITLE>
            </HEAD>
            <BODY>
            <xsl:call-template name="instancier-entête">
                <xsl:with-param name="next" select="concat( $next, '.html')" />
                <xsl:with-param name="prev" select="concat( $prev, '.html')" />
            </xsl:call-template>
                
            <TABLE width="100%" height="90%" BORDER="0" CELLSPACING="10">
            <TR valign="top"><TD>
                <xsl:apply-templates select="//pageStandard" mode="plan"/>
            </TD></TR>
            </TABLE>
            
            <xsl:call-template name="instancier-piedDePage"/>
            </BODY>
        </HTML>
        </xsl:document>
        
    </xsl:template>
    
    
</xsl:stylesheet>
XML.2.html
<HTML>
   <HEAD>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   
      <TITLE>Cours XML</TITLE>
   </HEAD>
   <BODY>
      <TABLE valign="top" width="100%" height="2%" BORDER="0" CELLSPACING="0" 
      BGCOLOR="#FFFF99">
         <TR>
            <TD width="33%" align="left"><A HREF="Table.html">
            Page pr&eacute;c&eacute;dente</A></TD>
            <TD width="34%" align="center"><A HREF="Table.html">Table</A></TD>
            <TD width="33%" align="right"><A HREF=".html">Page suivante</A>
            </TD>
         </TR>
      </TABLE>
      <TABLE width="100%" height="90%" BORDER="0" CELLSPACING="10">
         <TR valign="top">
            <TD>
               <H1 align="left"> XML - G&eacute;n&eacute;ralit&eacute;s </H1>
               <UL TYPE="SQUARE">
                  <LI>
                     XML est un langage de balisage de textes.
                  </LI>
               </UL>
               <H2 align="left"> Balisage </H2>
               <UL TYPE="SQUARE">
                  <LI>
                    Le principe d'un langage de balisage de textes 
                    existe depuis fort longtemps, 
                    avant m&ecirc;me l'invention de l'informatique.
                  </LI>
                  <UL TYPE="CIRCLE">
                     <LI>
                        en imprimerie, le texte de l'&eacute;preuve est 
                        balis&eacute;e de 
                        "corrections" &agrave; effectuer (balises textuelles),
                     </LI>
                     <LI>
                        et les relectures &agrave; voix haute, chez les 
                        typographes,
                        se font agr&eacute;ment&eacute;es de balises vocales 
                        codifi&eacute;es, avec tout un 
                        argot de m&eacute;tier assez savoureux (trouv&eacute; 
                        dans "Petite Histoire 
                        des signes de corrections typographiques", par Jacques 
                        Andr&eacute;, in 
                        Cahier GUTemberg No 31, D&eacute;cembre 1998) :
                     </LI>
                     <UL TYPE="DISC">
                        <LI>
                           le m&eacute;tro (invent&eacute; par 
                           Bienven&uuml;e ! ...)
                        </LI>
                        <LI>
                            le m&eacute;tro <B>ouvre</B> invent&eacute; 
                            par Bienven&uuml;e <B>cap couilles clame suce ferme
                                </B>
                        </LI>
                     </UL>
                  </UL>
               </UL>
               <UL TYPE="SQUARE">
                  <LI>
                    Avec l'invention de l'informatique, les techniques de 
                    balisages
                    se sont appliqu&eacute;es &agrave; la commande des 
                    Linotypes par bandes 
                    perfor&eacute;es, o&ugrave; le texte &agrave; composer 
                    &eacute;tait parsem&eacute; de commandes 
                    destin&eacute;es &agrave; la manoeuvre de la Lynotype 
                    elle m&ecirc;me (passer en gras,
                    changer de corps, faire un retrait, etc.).
              </LI>
               </UL>
            </TD>
         </TR>
      </TABLE>
      <TABLE valign="top" width="100%" height="2%" BORDER="0" CELLSPACING="0" BGCOLOR="#FFFF99">
         <TR>
            <TD width="33%" align="left">Ph. Drix - Objectiva</TD>
            <TD width="34%" align="center">Comprendre XML et XSL</TD>
            <TD width="33%" align="right">4</TD>
         </TR>
      </TABLE>
   </BODY>
</HTML>
Table.html
<HTML>
   <HEAD>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   
      <TITLE>Cours XML</TITLE>
   </HEAD>
   <BODY>
      <TABLE valign="top" width="100%" height="2%" BORDER="0" CELLSPACING="0" 
      BGCOLOR="#FFFF99">
         <TR>
            <TD width="33%" align="left"><A HREF="XML.1.html">
            Page pr&eacute;c&eacute;dente</A></TD>
            <TD width="34%" align="center"><A HREF="Table.html">Table</A>
            </TD>
            <TD width="33%" align="right"><A HREF="XML.2.html">
            Page suivante</A></TD>
         </TR>
      </TABLE>
      <TABLE width="100%" height="90%" BORDER="0" CELLSPACING="10">
         <TR valign="top">
            <TD>
               <H1 align="left"><A HREF="XML.1.html">D&eacute;roulement du 
               Cours</A></H1>
               <H1 align="left"><A HREF="XML.2.html"> 
               XML - G&eacute;n&eacute;ralit&eacute;s </A></H1>
               <H2 align="left"><A HREF="XML.2.html"> Balisage </A></H2>
            </TD>
         </TR>
      </TABLE>
      <TABLE valign="top" width="100%" height="2%" BORDER="0" CELLSPACING="0" 
      BGCOLOR="#FFFF99">
         <TR>
            <TD width="33%" align="left">Ph. Drix - Objectiva</TD>
            <TD width="34%" align="center">Comprendre XML et XSL</TD>
            <TD width="33%" align="right">3</TD>
         </TR>
      </TABLE>
   </BODY>
</HTML>
preceding-sibling::*[1] Table following-sibling::*[1]