copy et copy-of

copy-of
Nous avons vu comment générer une sortie basée sur la valeur textuelle des éléments du document XML initial. Il peut parfois être intéressant de générer en sortie un élément du document source sans y apporter de modification (i.e. copier dans l'arbre résultat une partie de l'arborescence source). C'est ce que réalise l'instruction copy-of :
XML source
<couples>
    <couple><form>Il</form><lemma>il</lemma></couple>
    <couple><form>était</form><lemma>être</lemma></couple>
    <couple><form>une</form><lemma>un</lemma></couple>
    <couple><form>fois</form><lemma>fois</lemma></couple>
<couples>
XSL XML résultat
<xsl:template match="/">
    <liste-items>
        <xsl:apply-templates/>
    </liste-items>
</xsl:template>

<xsl:template match="couple">
    <item>
        <num>

            <xsl:value-of select="position()"/>
        </num>
        <xsl:copy-of select="."/>
    </item>
</xsl:template>
   <liste-items>
    <item>
        <num>1</num>
         <couple>
             <form>Il</form>
             <lemma>il</lemma>
         </couple>
     </item>
     <item>
         <num>2</num>
         <couple>
             <form>était</form>
             <lemma>être</lemma>
         </couple>
     </item>
    <item>
         <num>3</num>
         <couple>
             <form>une</form>
             <lemma>un</lemma>
         </couple>
     </item>
     <item>
         <num>4</num>
         <couple>
             <form>fois</form>
             <lemma>fois</lemma>
         </couple>
     </item>
</liste-items>

copy
Nous venons de voir comment l'instruction copy-of permet de recopier intégralement l'élément XML désigné par l'attribut select. L'instruction copy, appliquée dans un patron, a pour effet de créer une paire de balises (ouvrante et fermante) dont le nom est celui de l'élément courant. Dans l'exemple précédent, si nous remplaçons l'instruction <xsl:copy-of select="."/> par <xsl:copy/>, nous obtenons le résultat suivant :
<liste-items>
    <item><num>1</num><couple/></item>
    <item><num>2</num><couple/></item>
    <item><num>3</num><couple/></item>
    <item><num>4</num><couple/></item>
</liste-items>
En effet, l'instruction <xsl:copy/> est équivalente à :
<xsl:element name="{name(.)}"/>
(element sera vu dans la page suivante)
L'instruction ne copie ni les descendants du noeud courant, ni les attributs éventuels. Une manière de copier les descendants peut être :
<xsl:template match="/">
    <liste-items>
        <xsl:apply-templates/>
    </liste-items>
</xsl:template>

<xsl:template match="couple">
    <item>
        <num>
            <xsl:value-of select="position()"/>
        </num>
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </item>
</xsl:template>

<!-- copie à l'identique de tous les descendants de couple -->
<xsl:template match="//couple//*">
    <xsl:copy-of select="."/>
</xsl:template>
 ou  <xsl:template match="/">
    <liste-items>
        <xsl:apply-templates/>
    </liste-items>
</xsl:template>

<xsl:template match="couple">
    <item>
        <num>
            <xsl:value-of select="position()"/>
        </num>
        <xsl:copy>
            <!-- copie de tous les enfants -->
            <xsl:copy-of select="./*"/>
        </xsl:copy>
    </item>
</xsl:template>
On peut également ajouter dans l'élément en cours de copie des éléments nouveaux. Dans l'exemple précédent, si l'on veut faire en sorte que l'élément num soit imbriqué dans l'élément couple, on peut écrire (suppression de la balise item et déplacement de la balise num) :
XSL Résultat
<xsl:template match="/">
    <liste-items>
        <xsl:apply-templates/>
    </liste-items>
</xsl:template>

<xsl:template match="couple">
    <xsl:copy>
        <num>
            <xsl:value-of select="position()"/>  
        </num>

        <xsl:copy-of select="./*"/>
    </xsl:copy>
</xsl:template>
   <liste-items>
    <couple>
        <num>1</num>
        <form>Il</form>
        <lemma>il</lemma>  
    </couple>
    ...
</liste-items>

Revenons sur l'exemple de départ :
<?xml version="1.0" encoding="iso-8859-1"?>
<doc>
    <taggersent id="sent-1">
        <taggertoken wordform="Il" lemma="il" pos="PRO"/>
        <taggertoken wordform="était" lemma="être" pos="VER:sg"/>
        <taggertoken wordform="une" lemma="un" pos="DET:femi:sg"/>
        <taggertoken wordform="fois" lemma="fois" pos="NOM:femi:sg"/>
        ...
    </taggersent>
</doc>
et supposons que pour chaque token, nous voulions insérer un jalon pour obtenir (en vue d'un traitement quelconque) un résultat du type :
<?xml version="1.0" encoding="iso-8859-1"?>
<doc>
    <taggersent id="sent-1">
        <milestone id="1"/><taggertoken wordform="Il" lemma="il" pos="PRO"/>
        <milestone id="2"/><taggertoken wordform="était" lemma="être" pos="VER:sg"/>
        <milestone id="3"/><taggertoken wordform="une" lemma="un" pos="DET:femi:sg"/>
        <milestone id="4"/><taggertoken wordform="fois" lemma="fois" pos="NOM:femi:sg"/>
        ...
    </taggersent>
</doc>

Si nous écrivons la feuille suivante :    nous obtenons :
<xsl:template match="*">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="taggertoken"> 
    <milestone id="{position()}"/>
    <xsl:copy>
        <xsl:copy-of select="./*"/>
    </xsl:copy>
</xsl:template>

<doc>
    <taggersent>
        <milestone id="1"/><taggertoken/>
        <milestone id="2"/><taggertoken/>
        <milestone id="3"/><taggertoken/>
        <milestone id="4"/><taggertoken/> 
    </taggersent>
</doc>

Il faut donc les générer explicitement :
XSL
   (les attributs n'ont pas été reproduits)

Résultat
<xsl:template match="*">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="taggertoken"> 
    <milestone id="{position()}"/>
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:copy-of select="./*"/>
    </xsl:copy>
</xsl:template>

<doc>
    <taggersent id="sent-1">
        <milestone id="1"/><taggertoken lemma="il" pos="PRO" wordform="Il"/>
        <milestone id="2"/><taggertoken lemma="être" pos="VER:sg" wordform="était"/>
        <milestone id="3"/><taggertoken lemma="un" pos="DET:femi:sg" wordform="une"/>
        <milestone id="4"/><taggertoken lemma="fois" pos="NOM:femi:sg" wordform="fois"/> 
    </taggersent>
</doc>
Précédent... ] Sommaire... ] Suivant... ]