Your Federal Quarterly Tax Payments are due April 15th Get Help Now >>

XSLT XML Stylesheet Language Transformation by bns26590

VIEWS: 28 PAGES: 129

									       XSLT : XML Stylesheet
      Language Transformation
          Une introduction à XSLT pour
               l'analyse de corpus

Sylvain Loiseau <sylvain.loiseau@u-paris10.fr>
Introduction




               2
• Note : pour apprendre ce langage il est
  indispensable de disposer d’un processeur
  et de tester et modifier les exemples du
  diaporama.




                                          3
            « Feuille de style »
           et « transformation »
• Le programme XSLT est appelé une « feuille de
  style »
• La feuille de style est fournie, avec un document
  XML, à un programme (un « processeur XSLT »)
• Le processeur « transforme » le document en
  fonction des instructions de la feuille de style et
  produit en sortie un nouveau document.
                    XSLT



  XML                                XML / HTML / texte
               Processeur XSLT
                                                          4
Principe de la transformation XSLT
• La feuille de style décrit des règles de
  transformation que le processeur applique au
  document
• Pour cette transformation on peut sélectionner des
  données dans le document source
    Les requêtes peuvent utiliser les noms et ordre des
    balises, noms et valeurs des attributs, contenu du texte,
    position dans l’arborescence (contexte), etc.
• On peut également manipuler ces données (tri,
  décompte, etc.) et ajouter des éléments nouveaux.
                                                          5
           Le processeur transforme le
              document en un autre
                                          Feuille de style
                                              XSLT :
                                            règles de la
                                          transformation



                       teiHeader                                    Racine

                fileDesc                                     truc            machin
Document                                   Transformation                             Document
  XML                              Text                                       Text      XML
             title    Text
 source                                                                                produit




                                            Processeur                                    6
           Exemples d’utilisation
• Rechercher des éléments du corpus
   – En utilisant toutes les propriétés du document
• Composer des sous corpus
   – Texte sans les <note>, seulement les <note>…
• Quantifications
   – Pourcentage des <foreign> dans les <note>
• Convertir d'un format à l'autre
   – XML vers Hyperbase, Unitexte, sans balise, etc.; ou vers
     des formats de lecture : HTML, PDF, Word, etc.
• Maintenance et enrichissement du corpus
   – Possibilité (limitée) d’ajouter de l’information     7
  Intérêt du couple XML/XSLT
• On ne maintient pas différentes versions
  du corpus pour les différents formats ou
  les différents sous-corpus
• On peut appliquer les mêmes feuilles de
  style à plusieurs corpus.
• Pas de programmation



                                             8
       Objectif du diaporama
• Introduction aux principes et aux
  principales fonctions de XSLT
• Application pour l’utilisation de corpus.
• Proposer différentes approches pour les
  principales tâches : extraire des
  informations, calculer des valeurs
  numériques, convertir vers d’autres
  formats, lister des valeurs, et ajouter de
  l’information.
                                               9
    Une première feuille de style

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

  <xsl:template match="/">       Préfixé par « xsl: » = des
      <html>                        instructions XSLT, ici
      <body>                     d’organisation de la feuille
      <p>Hello, world</p>                  de style
      </body>
      </html>                        Texte non-préfixé par
  </xsl:template>                        « xsl: » : recopié
                                     littéralement en sortie
</xsl:stylesheet>


                                                           10
                         Résultat :
        <html>
        <body>
        <p>Hello, world</p>
        </body>
        </html>

• Le processeur lit la feuille, imprime ce qui est littéral (le texte
  ou les balises non préfixés par « xsl: ») et évalue/exécute les
  instructions (préfixées par « xsl: »)
• Cette feuille de style ne contient que des éléments « littéraux »
  : elle n’extrait aucune information du document
• Ici les balises rajoutées sont du HTML : à partir du document
  on génère une page HTML. Le résultat de la transformation
  peut être ouvert et affiché dans un navigateur. (Fichier->Ouvrir
  dans Internet Explorer) Ce n’est pas obligatoire : on peut aussi
  écrire des balises non-HTML, ou ne mettre aucune balise dans       11
  le résultat.
             Pour résumer
• Une feuille de style est un document XML
  – L'élément racine est xsl:stylesheet avec
    deux attributs obligatoires
  – La feuille de style contient un élément
    xsl:template
• Tout ce qui est "préfixé" par xsl: est une
  instruction XSLT, qui est exécutée par le
  processeur et remplacée par son résultat.
• Tout ce qui n'est pas "préfixé" est
  reproduit littéralement
                                             12
Extraire des informations
Extraire le texte contenu dans une balise

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

   <xsl:template match="/">
       <html><body>
       <p>Titre du corpus :
 <xsl:value-of select =
   "/teiCorpus.2/teiHeader/fileDesc/titleStmt/title"/>
       </p>
       </body>
       </html>
   </xsl:template>

 </xsl:stylesheet>
                                                       14
   L'instruction xsl:value-of
<xsl:value-of select="/TEI.2/.../title"/>



Remplacer cette instruction   … trouvée à cet endroit
par le texte…




La valeur de l'attribut select est une
expression XPath : elle désigne un endroit
du document où aller chercher le texte.                 15
"/TEI.2/teiHeader/fileDesc/titleStmt/title"
                                                Document
                                                    /




            PI                                                             Element
   <?xml version=“1.0”?>                                                    TEI.2




                                                   Element
                                                   teiHeader




          Element                    Element                   Element   Element
             …                       fileDesc                     …         …




           Text                                                 Text      Text
                           Element
                                                Text
                             title



                            Text                                                     16
<xsl:value-of select="/corpus/text/p/name"/>

                                                  Document
                                                      /




               PI                                                              Element
      <?xml version=“1.0”?>                                                     corpus


Bien qu’il y ait plusieurs p, un
seul chemin satisfait
                                                         Element
entièrement à l’expression (un                             text
seul p a un élément name)

             Element                    Element                    Element   Element
                p                          p                          p         p




              Text                                                  Text      Text
                              Element
                                                  Text
                               name



                               Text                                                      17
                    XPath
• XPath est une autre recommandation, comprise
  dans XSLT
• XPath remplit la fonction de "sélectionner",
  "pointer" sur des éléments du document, tandis
  que XSLT organise, trie, etc.
• XPath retourne des nœuds de l'arborescence,
  par exemple des balises, des attributs, des
  nœuds textes.
• XPath permet de désigner les propriétés XML
  (nom des balises et attribut, contexte, ordre…)
                                                18
xsl:value-of convertit le nœud en texte :
      supprime les balises incluses
Instruction XSLT …

<xsl:value-of select="p" />


… sur ce document XML

<p>du texte et <hi
rend="italics">d'autres</hi> éléments</p>

XPath retourne un « nœud », XSLT converti en texte :

du texte et d'autres éléments
                                                       19
Si plusieurs éléments correspondent ?
 <xsl:value-of select="/TEI.2/text/body/p"/>

 • Il y a sans doute beaucoup de p qui
   correspondent à ce chemin.
 • XPath les retourne tous, mais la fonction
   xsl:value-of ne sélectionne que le
   premier pour l'afficher.



                                               20
             xsl:for-each
• Si on veut traiter tous les nœuds retournés
  par l'expression XPath, il faut utiliser
  xsl:for-each

<xsl:for-each select="expression XPath">
     On traite une à une les valeurs trouvées
</xsl:for-each>




                                                21
<xsl:for-each select="/teiCorpus.2/TEI.2/text/p">
      <para><i><xsl:value-of select="." /></i></para>
</xsl:for-each>



<p>Premier <hi rend="italics">paragraphe</hi>
éléments</p>
<p>Second paragraphe</p>
<p>Troisième paragraphe</p>



<para><i>Premier éléments</i></para>
<para><i>Second paragraphe</i></para>
<para><i>Troisième paragraphe</i></para>
                                                    22
<xsl:for-each select="/teiCorpus.2/TEI.2/text/p">
      <p><i><xsl:value-of select="." /></i></p>
</xsl:for-each>

                                                                  Element
                                                                   TEI.2




                                            Element
                                              text




       Element             Element                    Element   Element
          p                   p                          p         p




       Text                                            Text      Text
                 Element
                                     Text
                  name



                  Text                                                      23
• xsl:for-each regroupe d’abord les nœuds
  avec select, ensuite exécute le contenu de la
  boucle autant de fois qu’il y a de nœuds
  - L'expression XPath de select trouve quatre nœuds.
    S'il n'y avait qu'un seul élément, ou zéro, la boucle
    serait exécutée une ou zéro fois.
  - À chaque passage on traite un des nœuds trouvés,
    qui devient le "nœud contexte" durant ce passage et
    peut être désigné par «.».
  - Dans le contenu de la boucle, on peut se déplacer à
    nouveau dans l'arborescence, mettre un élément
    littéral, etc.
                                                        24
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html><body>
    <p>Titre du corpus :
      <xsl:value-of select =
      "/teiCorpus.2/teiHeader/fileDesc/titleStmt/title"/>
    </p>
    <xsl:for-each select="/teiCorpus.2/TEI.2">
      <p>Titre :
  <xsl:value-of select="teiHeader/fileDesc/titleStmt"/>
      </p>
    </xsl:for-each>
    </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
                                                    25
                        <xsl:for-each select="/teiCorpus.2/TEI.2">


                                                 Element
                                                    …




       Element                     Element                 Element        Element
        TEI.2                       TEI.2                   TEI.2          TEI.2
       …                                                    …               …
                                                           A chaque itération on
                         Element             Element       applique une nouvelle
                            …                   …
                                                           recherche XPath


             Element               Element
               title                  …

                 Text



<xsl:value-of select="teiHeader/fileDesc/titleStmt/title"/>
                                                         26
                  Le contexte
• Il y a toujours un nœud contexte quand une
  instruction est exécutée.
   – Ce nœud contexte peut être désigné explicitement
     avec "."
   – C'est à partir du nœud contexte que sont évaluées les
     expressions XPath qui ne commencent pas par "/" :
select="teiHeader/fileDesc/titleStmt"
  On désigne, par rapport au nœud contexte, un endroit
  de la sous-arborescence. On aurait pu écrire aussi :
select="./teiHeader/fileDesc/titleStmt"

                                                         27
  Une utilisation de xsl:for-each :
faire une table des matières du corpus

 • On ne sait pas combien de textes ni de
   titres de niveau 1, 2, etc., il peut y avoir
 • Il faut traiter tous les textes, et dans
   chaque texte traiter les niveaux 1, dans
   chaque niveau 1 traiter les niveaux 2, etc.
 • On peut donc imbriquer des boucles
   xsl:for-each

                                                  28
       Une table des matières (1)
• On extrait le titre de chaque texte dans le
  corpus :
<xsl:for-each select="/teiCorpus.2/TEI.2">
<p>Titre :
       <xsl:value-of
       select="teiHeader/fileDesc/titleStmt/title"/>
</p>
<hr />
</xsl:for-each>



Cf. ci-joint le fichier TableDesMatieres.xsl

                                                       29
       Une table des matières (2)
 • A l'intérieur du for-each, à chaque itération, le
   nœud contexte est donc l'élément TEI.2 traité
 • On peut lancer une nouvelle boucle, dans la
   première, pour chercher les titres de niveaux 1
   dans cet élément TEI.2              L’expression XPath ne
<xsl:for-each select="/teiCorpus.2/TEI.2"> commence pas par « / »
<p>Titre :                                        : text est recherché
     <xsl:value-of select=                        parmi les enfants du
     "teiHeader/fileDesc/titleStmt/title"/> nœud contexte (le TEI.2
</p>                                              traité)
     <xsl:for-each select="text/body/div[@type = '1']">
         <h1><xsl:value-of select="head"/></h1>
     </xsl:for-each>
<hr />
                            Par rapport au nouveau contexte (div),
</xsl:for-each>                                                        30
                            on désigne le premier enfant head
select="text/body/div[@type = '1']"
1. Ce qui est entre crochets est un prédicat : permet
   de filtrer les éléments sélectionnés.
2. @ permet de désigner un attribut.
3. Respecter l’alternance guillemets / apostrophes

<xsl:value-of select="head"/>
Sélectionne le premier élément head directement en
dessous de div. On aurait pu écrire aussi :
<xsl:value-of select="./head"/>                         31
      Une table des matières (3)
 <xsl:for-each select="/teiCorpus.2/TEI.2">
    <p>Titre : <xsl:value-of
select="teiHeader/fileDesc/titleStmt/title"/></p>

    <xsl:for-each select="text/body/div[@type = '1']">
      <h1><xsl:value-of select="./head"/></h1>
      <xsl:for-each select="div[@type = '2']">
        <h2><xsl:value-of select="./head"/></h2>
        <xsl:for-each select="div[@type = '3']">
          <h3><xsl:value-of select="./head"/></h3>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>

  <hr />
  </xsl:for-each>                                   32
      Classer avec xsl:sort
<xsl:for-each select="/teiCorpus.2/TEI.2">
  <xsl:sort
  select=“teiHeader/fileDesc/titleStmt/title"
  order="ascending"/>
<!-- les textes sont classés par leur titre-->
  <xsl:value-of select="." />
</xsl:for-each>


Les éléments sont extraits avec for-each ; avant
d’être traités un à un, ils sont classés par xsl:sort,
ici par ordre alphanumérique (« ascending »), en
fonction du contenu du select de sort (ici les
                                                       33
textes sont donc classés par leur titre).
           Ajouter un index
• xsl:number permet de retourner un
  nombre correspondant à l'index de
  l'élément dans le node set.
<xsl:for-each select="/teiCorpus.2/TEI.2">
  <xsl:number value="position()" format="1. "/>
  <xsl:value-of select="." />
</xsl:for-each>

1. Premier titre
2. Second Titre
3. Etc
                                              34
               xsl:output
• Indiquer le jeu de caractères de la sortie avec
  <output encoding='...'>
• Indiquer le type de sortie (text, XML, HTML) avec
  mode (Permet d’ajouter le prologue XML ou HTML)
<xsl:stylesheet version="1.0"
     xmlns:xsl=
     "http://www.w3.org/1999/XSL/Transform">
  <xsl:output
     encoding="iso-8859-1"
     mode="html" />

                                                    35
      Résumé XPath

XPath permet d’écrire des « chemins
XML » mais également d’utiliser des
    fonctions et des opérateurs.
         XPath : les « chemins »
            en quatre points
• XPath permet de pointer sur des éléments de
  l'arborescence du document.
• Une expression XPath est constituée (1) d'étapes (steps),
  séparées par des slashs
• Chaque étape contient (2) un nœud asserté (?) (node test) :
  le nom d’un élément, attribut, etc.
• Optionnellement le node set peut avoir (3) un prédicat (à
  droite) et (4) un axe (à gauche)
• L'expression retourne un sac de nœuds : les nœuds qui
  correspondent au dernier nœud asserté – si elle en trouve.


"/TEI.2/text/body/div[@type='intro']/head"
                                                        37
             (1) les étapes
• Le slash indique la relation parent / enfant
• Un double slash indique la relation parent /
  descendants (à toute profondeur dans la
  hiérarchie).
 /TEI.2[1]/text/body//name[@type='np']
  – Note : temps de calcul accru
• Un slash en début fait partir l'expression de
  la racine du document : l'expression est
  donc indépendante du contexte.
                                             38
                       Exemples
teiCorpus.2/TEI.2/teiHeader
//TEI.2[1]//p
• Note : "//" part de la racine :
   – "//p" : tous les p du document, à toute profondeur depuis la racine
   – ".//p" : tous les p sous le nœud contexte
• Différences entre :
   – //TEI.2/text//div/p
     Les p directement en dessous de tous les div
   – //TEI.2/text/div//p
     Tous les p en dessous de div directement en dessous de text
• Avec //TEI.2/text//div//p chaque p est
  sélectionné une fois dans le sac de nœuds résultant, même
  si plusieurs div sont imbriqués et font différents chemins
  valides vers le même p : il n’y a jamais de doublon dans un
  sac de nœuds.
                                                                   39
           (2) : les node tests
• Chaque étape comprend un node test
• Le nœud cherché peut être une balise, un
  attribut (@nom) ou un nœud texte (text())
• Existent également des valeurs génériques : *
  (tout élément), @* (tout attribut) , node() (tout
  nœud : texte, élément, attribut, PI, comment,…)
• Le point "." indique le contexte actuel
• Le double point ".." permet de remonter d'un
  niveau dans l'arborescence.

                                                  40
                      Exemples
•   //*[@rend = 'italics']/text()
•   teiCorpus.2/TEI.2[1]/teiHeader
•   //p[../liste]
•   //p/@id : retourne la valeur de l’attribut
•   Ne pas confondre un nœud texte et le texte contenu :
    – /TEI.2/text/front
      Retourne tout le texte contenu, sans les balises
    – /TEI.2/text/front/text()
      Retourne les nœuds texte directement enfants de front, avec
      value-of retourne uniquement le premier nœud :
      probablement un retour chariot…
    – TEI.2/text/front/@id/text()
      Ne retourne rien : il n'y a pas de nœud texte descendant
                                                            41
      d'un attribut. (@id retourne déjà la "valeur")
              (3) : les prédicats
• Chaque étape peut comprendre un prédicat, qui est une
  expression XPath entre crochets placée après le node test.
   – Ex. //div[@type='intro'] sélectionne les div ayant un attribut
     @type avec la valeur 'intro'
• Le prédicat permets de filtrer les nœuds en ajoutant des
  conditions.
• L’expression XPath dans le prédicat peut avoir deux
  valeurs : vraie ou fausse.
• L’expression XPath est convertie si besoin en valeur
  booléenne : est faux un sac de nœud vide, le nombre zéro
  ou la chaîne vide, est vrai tout le reste.
   – Dans le premier exemple, l’expression retourne déjà une valeur
     booléenne grâce à l’opérateur « = »
   – Ex. //p[name] sélectionne tous les p contenant un élément enfant
     « name ». p est le contexte de l’expression XPath « name ». 42
       Fonctions XPath utiles
• Les conditions sur la position d’un nœud sont
  souvent utilisées dans les prédicats.
• Les fonctions last() et position() renvoie
  respectivement le numéro du dernier nœud d’un
  sac de nœuds et le numéro du nœud courant.
  – Note : last() et position() s’écrivent toujours
    avec les parenthèses et sans argument.
  – Plutôt que [position() = 1], pour demander les
    nœuds qui sont le premier enfant de leur père, on
    peut utiliser une notation courte [1].

                                                        43
                                 Exemples
<xsl:for-each select="/teiCorpus.2//hi[@rend = „italics‟]">
           <!-- tous les tags hi avec un attribut rend = italics -->
</xsl:for-each>

<xsl:for-each select="//TEI.2[1]/text/p[name/@id]">
           <!-- tous les p qui ont un enfant name qui a un attribut id -->
</xsl:for-each>

<xsl:for-each select="//TEI.2[1]/text/p [not(position()=last())]">
           <!– tous les p qui ne sont pas les derniers parmi les éléments ayant le même
parent -->
</xsl:for-each>

<xsl:for-each select="//TEI.2[1]/text/p[position() != last())]">
           <!-- autre notation -->
</xsl:for-each>

<xsl:for-each select="//TEI.2[1]/text/p[position() &gt; 1]">
           <!-- tous les p sauf le premier -->
                                                                                          44
</xsl:for-each>
<xsl:value-of     select="text/p[3]"/>
<xsl:value-of     select="text/p[name]"/>
<xsl:value-of     select="text/p/name"/>
<xsl:value-of     select="text[p/name]/p[3]"/>
<xsl:value-of     select="text/p[name/@n]"/>
<xsl:value-of     select="text/p[not(text())]"/>
<xsl:value-of     select="text/p[last()]"/>
<xsl:value-of select="text/p[not(position() = last())]"/>
                                           Element
                                             text




        Element              Element                 Element   Element
           p                    p                       p         p




         Text                                         Text      Text
                   Element
                    name
                                       id='p5'

                    Text
        n='8'
              (4) : les axes
• Dans la forme abrégée de la syntaxe XPath
  utilisée jusqu'ici, les node test sont cherchés
  parmi les enfants de l'étape précédente, ou
  parmi les descendants avec //.
• Il est donc impossible dans cette notation
  d'indiquer un chemin qui remonte vers les
  autres directions : ancêtres, parents,
  descendants, ou frères du nœud contexte :

                                              46
XML, une histoire
de famille                                      Document
                                                    /




             PI                                                               Element
    <?xml version=“1.0”?>                                                      corpus


                                                                 Ancêtres
                                                       Element
                                                         text
                                                                  Parent
Frêres
           Element                    Element                    Element    Element
              p                          p                          p          p




            Text                                                  Text       Text
                            Element
                                                Text
                             name


                                                   Enfants
                             Text
                                                Descendants                             47
                 Noter les axes
• On peut désigner à chaque étape d'autres
  directions que l’axe parent / enfant grâce à
  une « notation longue » : le note test est
  précédé du nom de l'axe suivi de "::"
• Exemple
   –select="./ancestor::div"    Recherche le premier div parmi les
                                ascendants
                                         Remonte au TEI.2 ascendant,
   –Select="./ancestor::TEI.2/teiHeader puis descend à son enfant direct
                                         teiHeader
   –Following-sibling::node() | Sélectionne n’importe quel type de nœud
                                descendant du même père, soit à droite
   preceding-sibling::node()
                                  sinon à gauche                    48
                                  Document
                                      /




         PI                                                        Element
<?xml version=“1.0”?>                                            FitnessCenter



                                                                        Ancêtres
                                     Element
                                     Member          Parent


       Element          Element                  Element        Element
        Name             Phone                    Phone       FavoriteColor


          Frêre précédent           Frêres Suivants

        Text            Element                   Text             Text
        Jeff             Name                   555-4321        lightgrey

                                       Enfant

                         Text                Descendants                           49
                         Jeff
                                                      Document
                                                          /




                PI                                                                          Element
       <?xml version=“1.0”?>                                                              FitnessCenter




                                                          Element
                                     ancêtre              Member




              Element                     Element                      Element           Element
               Name                        Phone                        Phone          FavoriteColor
                        Frêre précédent              Frêres suivants


               Text                         Text                         Text               Text
               Jeff                       555-1234                     555-4321          lightgrey




ancestor::* sélectionnera tous             preceding-sibling::*                   following-sibling::*
les ancêtres, c’est à dire :               sélectionnera tous les frêres à        sélectionnera tous les frêres à
- Member                                   gauche, c’est à dire :                 droite, c’est à dire :
- FitnessCenter                            - Name                                 - Phone                  50
                                                                                  - FavoriteColor
                                        Document
                                            /




         PI                                                                        Element
<?xml version=“1.0”?>                                           descendants      FitnessCenter




                                           Element
                                           Member




       Element               Element                 Element                    Element
        Name                  Phone                   Phone                   FavoriteColor




        Text                   Text                    Text                        Text
        Jeff                 555-1234                555-4321                   lightgrey



                        À partir de FitnessCenter, descendant::*
                        sélectionnera tous les descendants, c’est à dire :
                        - Member
                        - Name                                                                   51
                        - Phone, etc
                      Liste des axes
• ancestor: sélectionne tous les ancestors
• ancestor-or-self: sélectionne tous les le noeud courant et tous ses
  ancêtres
• attribute: sélectionne tous les attributs
• child: sélectionne tous les enfants (descendants directs)
• descendant: sélectionne tous les descendants
• descendant-or-self: sélectionne le noeud courant plus tous ses
  descendants
• following: sélectionne tout ce qui suit le noeud courant dans le document
• following-sibling: sélectionne tous les frêres à droite
• namespace: sélectionne tous les namespaces ouverts
• parent: sélectionne le parent
• preceding: sélectionne tout ce qui précède le noeud courant dans le
  document
• preceding-sibling: sélectionne tous les frêres à gauche
• self: sélectionne le noeud courant
                                                                          52
Exemples




           53
• L'axe child:: est l'axe par défaut, "@«
  abrège l'axe attribute::, "//" abrège
  descendant-or-self::, "." abrège l'axe self::
  et ".." l'axe parent::.




                                                  54
        Principaux opérateurs
• Opérateurs arithmétiques +, -, *, div,
  mod
  – Note : une balise XML peut contenir un tiret, il faut
    donc encadrer “-” d’espace.
• Operateurs booléens : not, and, or
• Operateurs relationnels :
  <, >, =, <=, >=, !=, | (ou), & (et)
  – < et > doivent être notés &lt; et &gt; pour satisfaire
     aux contraintes XML.
Pour exprimer :    <     >      = <=         >=          !=
Noter :         &lt; &gt; = &lt;= &gt;= !=
                                                            55
 Rappel XML : ordre des éléments
     et valeur des attributs
• On ne peut pas accéder aux attributs par leur
  numéro d'ordre : ils sont accessibles seulement par
  leur nom, leur ordre n'est pas signifiant.
  impossible : @type[1] ou //*[@type[1]]
• Ainsi, dans la conception d'un document XML, il ne
  faut pas confier d'information à l'ordre des attributs.
• Les éléments correspondent un peu aux structures
  de données informatiques dites "tableaux" et les
  attributs aux tableaux associatifs ou "hashes"

                                                     56
Expression de conditions
Opération sur les chaînes
                        xsl:if
 <xsl:if test="expression XPath"/>

Permet de filtrer ou de choisir entre différentes possibilités.
Si l’expression XPath de @test renvoie une valeur non
nulle ou vraie, alors le contenu de xsl:if est exécuté.
 <xsl:if test="TEI.2[1]//sourceDesc">
      <p>
      Le premier texte du corpus
      a un élément sourceDesc
      </p>
 </xsl:if>
                                                             58
       Exemples de xsl:if

<xsl:for-each select="name">
    <xsl:if test="@type='person'">
        <xsl:value-of select='.'>
    </xsl:if>
</xsl:for-each>

            Ici c'est l'équivalent de :

<xsl:for-each select="name[@type='person']">
    <xsl:value-of select='.'>
</xsl:for-each>
                                          59
Dans le contexte de xsl:if, XPath
  retourne une valeur booléenne
• Une expression XPath peut être utilisée
  avec xsl:if pour voir si elle retourne vrai
  ou faux :
  – Elle retourne vrai si elle trouve des nœuds.
  – Elle retourne faux si elle ne trouve rien.




                                                   60
                 xsl:choose
• Exprimer des alternatives avec xsl:choose. Le
  premier élément when dont le test est positif est
  exécuté.
  <xsl:choose>
          <xsl:when test='expression XPath'>
                [action]
          </xsl:when>
          <xsl:when test='expression XPath'>
                [action]
          </xsl:when>
          <xsl:otherwise>
                [action]
          </xsl:otherwise>
  </xsl:choose>                                       61
...
<xsl:template match="/">
...
 <xsl:for-each select="/teiCorpus.2/TEI.2">
    <p>Titre : <xsl:value-of
       select="teiHeader/fileDesc/titleStmt/title"/></p>
      <xsl:if select="teiHeader/fileDesc/sourceDesc">
          <p>
            Source du texte :
            <xsl:if select=".//author">
               <xsl:value-of select="." />
            </xsl:if>
            <xsl:if select=".//docDate">
               <xsl:text> (</xsl:text>
               <xsl:value-of select="." />
               <xsl:text>), </xsl:text>
            <xsl:if>
            <xsl:if select=".//title">
               <i><xsl:value-of select="title" /></i>
            <xsl:if>
          </p>
      </xsl:if>
                                                           62
...
       Extraire une sous-chaîne
• Dans un nœud texte, on peut extraire une sous
  chaîne.
  ex. Extraire la date seule dans "value = "2002""
• Utiliser la fonction XPath "substring-after()"
  qui prend deux arguments
  – La chaîne source
  – La chaîne à partir de laquelle sélectionner le texte.



   substring-after(chaîne, pattern)
                                                            63
                      Exemple
 <xsl:if test="docDate">
   <xsl:text> (</xsl:text>
   <xsl:value-of select=
   "substring-after(docDate, '= ')" />
   <xsl:text>), </xsl:text>
 <xsl:if>



docDate
                 substring-after(docDate, „= ‟)
value = "2002"                                    "2002"
                                                           64
• XPath dans ce cas retourne une chaîne, et
  non plus un « sac de nœuds ».
• En attendant XSLT 2.0 et les expressions
  régulières, les fonctions chaînes de XPath
  sont nombreuses mais rudimentaires:




                                           65
       Fonctions sur des chaînes
  substring-before(chaîne, pattern)
  substring-after(chaîne, pattern)
  substring(chaîne, index, len?)
      ex: substring(‘1234567890’, 2, 5) => ‘23456’
  string-length(chaîne)
      ex: string-length(‘1234567890’) => 10
  concat(chaîne cible, chaîne à ajouter)
• Deux fonctions sur les chaînes retournent une valeur
  booléenne :
  starts-with()
      ex: <xsl:if test="starts-with(docDate, 'va')">
            [action]
          </xsl:if>
  contains(chaîne à tester, chaîne test)
  ex: <xsl:for-each select=“docDate[contains(., ‘2002')]">
      <!-- Sélectionne les noeuds contenant 2002 -->
                                                      66
• Exemple d'utilisation : on veut les éléments en
  italique, avec la valeur IT dans l'attribut @rend.
• Mais @rend peut également contenir "IT BO"
  ou "BO IT" pour marquer italique + gras, etc.
• On ne les extraira pas si on utilise
  select="//*[@rend = 'IT']", qui
  recherchera les @rend avec comme valeur
  exactement IT.
• contains permet ici de récupérer tous les
  italiques

 Select="//*[contains(@rend, 'IT')]"               67
• Ces fonctions ne sont utiles que sur des
  contenus très normalisés : XSLT n’est pas
  adapté au traitement de chaînes de
  caractères.
  – Impossible par exemple de s’en servir pour
    extraire les phrases en se basant sur la
    ponctuation



                                                 68
Quantifier
 count(), la fonction magique
• Cette fonction XPath permet de retourner
  le nombre de nœuds trouvés dans
  l’expression XPath entre parenthèses
• Permet de dénombrer tout phénomène
  exprimé en XML
<xsl:value-of select=
     "count(//p[@type = 'intro'])"/>
<xsl:value-of select=
     "count(//*[@lang = 'en'])"/>
<xsl:value-of select=
     "count(//div/p[1]/*[@ana= 'exemple'])"/>
                                             70
        Utiliser des variables
• Jusqu’à présent on a systématiquement
  mis le résultat d’une expression XPath
  dans xsl:value-of, qui affiche
  directement le résultat.
• Mais si l’on veut stocker et manipuler la
  valeur, pour afficher par exemple un
  pourcentage plutôt que le chiffre brut ?


                                              71
               xsl:variable
• xsl:variable permet de strocker puis de
  réutiliser une chaîne ou un fragment d’arbre.
• On crée une variable avec xsl:variable
  <xsl:variable name='hello' select="hello world"/>
    @name pour lui donner un nom
    @select : calculer sa valeur (expression XPath ou texte littéral)

• On désigne la valeur de la variable avec le
  nom préfixé de $ dans une expression XPath
  <xsl:value-of select="$hello"/>

           Nom de la variable :         hello
                                                                 72
            Valeur de la variable :   Hello World
   Stocker une valeur calculée
<xsl:variable name="nbrDiv"
     select="count(//div)" />
<xsl:variable name="nbrDiv1"
     select="count(//div[@type = '1'])" />
<xsl:variable name="nbrDiv2"
     select="count(//div[@type = '2'])" />
Pourcentage de section de niveau 1 :
<xsl:value-of
     select="($nbrDiv1 * 100) div $nbrDiv" />
Pourcentage de section de niveau 2 :
<xsl:value-of
     select="($nbrDiv1 * 100) div $nbrDiv" />

•Évite de recalculer plusieurs fois count(//div)
•Code plus lisible                            73
         Portée des variables
• Une variable reste utilisable dans tout l’élément
  dans lequel elle a été déclarée dans la feuille de
  style et dans les sous-éléments de celui-ci. Une
  fois sortie de cet élément, elle est détruite
  – Une variable déclarée directement comme enfant de
    xsl:stylesheet peut être utilisée dans toute la
    feuille de style.
  – Une variable déclarée dans un élément
    (xsl:template, xsl:if, etc.) ne peut être
    utilisée que dans cet élément et ses sous-éléments.

                                                          74
Quelques fonctions arithmétiques

 • sum(node set) calcule la somme de toutes les
   valeurs présentes dans le node set
 • round(numbre) arrondit number à l’entier le plus
   proche
    – Exemple round(2.3) retourne 2
 • Etc.




                                                      75
         Utiliser un template
   pour calculer les pourcentages
• Problème : on répète n fois la même
  opération pour calculer des pourcentages
• Solution : factoriser cette opération
• XSLT permet de créer une sous-routine
  (un template) qui retourne une valeur en
  fonction d'arguments


                                             76
<xsl:template match="/">
  <xsl:variable name="nbrDiv" select="count(//div)" />
  <xsl:variable name="nbrDiv1" select="count(//div[@type = '1'])" />
  <xsl:variable name="nbrDiv2" select="count(//div[@type = '2'])" />

 Pourcentage de section de niveau 1 :
       <!– La formule du calcul du pourcentage est confiée à un
       template, auquel on transmet des arguments -->
 <xsl:call-template name="calculPourcentage">
                                                         Appel d’un template
   <xsl:with-param name="Nbr1" select="$nbrDiv1"/>
   <xsl:with-param name="Nbr2" select="$nbrDiv"/>        xsl:with-param permet
 </xsl:call-template>                                    de transmettre les
                                                               arguments
 Pourcentage de section de niveau 2 :
 <!-- etc. -->

<!-- calcul des pourcentages -->
<xsl:template name="calculPourcentage">                         xsl:param permet de
 <xsl:param name="Nbr1"/>                                       nommer les
 <xsl:param name="Nbr2"/>                                       arguments reçus
 <xsl:value-of select="($Nbr1 * 100) div $Nbr2"/>
</xsl:template>
                                                                                77
Utiliser des templates
       L'intérêt d'une approche
             "procédurale"
• Nous avons vu une façon d'utiliser XSLT
  où l'on sait où chercher l'information à
  extraire.
• Cette démarche est adaptée pour les cas
  où l'on fait une extraction de faible volume
  dans des endroits précis de la structure.
• Mais…


                                             79
L'intérêt d'une approche par templates
 • Si l'on veut, plutôt qu'extraire un élément,
   recopier la totalité du document sauf un
   élément ?
 • Ou si l'on veut extraire un grand nombre
   d'éléments ?
 • XML a une structure non limitée : il faudrait
   un nombre irréaliste de for-each et if
 • Il est plus économique dans ce cas
   d'indiquer ce que l'on veut enlever ou
   modifier que ce que l'on veut extraire.
                                              80
• Plutôt que de décrire des opérations, on
  dessine un nouvel arbre en indiquant
  seulement les points à modifier de l'arbre
  existant.




                                               81
           Retour en arrière
• Toutes les feuilles de style commençaient par
  <xsl:template match="/">
• Cet élément xsl:template sert à
  regrouper des actions à faire à un "moment"
  précis
• Ce moment est désigné dans l'attribut
  @match
• @match attend une expression XPath, ici "/"
  indique la racine du document.
• Un template avec match="/" est exécuté
  en premier, puisque la racine est la première
  chose que cherche le processeur.
                                             82
Comment utiliser les templates ?
• Il suffit, pour l’élément que l’on veut traiter, de lui
  faire un élément template avec un @match qui
  lui correspond.
   – @match peut correspondre à tout nœud : élément,
     attribut (avec @) ou texte (avec text()).
   – Exemple : un template qui s’appliquera à chaque
     élément TEI.2 dans le document :
      <xsl:template match="TEI.2">
       ...
      <xsl:template>



                                                       83
 Exemple : mettre un titre HTML à
          chaque texte
<xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

      <xsl:template match="TEI.2">
            <h1>nouveau texte :
            <xsl:value-of select=".//titleStmt/title" />
            </h1>
            <xsl:apply-templates />
      </xsl:template>

</xsl:stylesheet>

                                                     84
    xsl:apply-templates
• Dans l'exemple précédent, apply-
  templates sert à relancer l'analyse (la
  recherche d'un template avec un attribut
  match qui correspond) dans la sous-
  arborescence du nœud traité par le
  template
• Si on ne met pas apply-templates le
  processeur est « éteint », il abandonne
  tout ce qui est en dessous

                                         85
     Que fait le processeur ?
• Après avoir construit une représentation
  du document, le processeur rentre dans
  l'arborescence.
• Il cherche dans la feuille de style un
  template qui correspond à sa première
  position, qui est "/"
• S'il n'en trouve pas, il passe aux
  descendants et recommence.
• S’il trouve un nœud texte, il imprime son
  contenu.
                                              86
                                                             Le processeur parcours les
                                                             éléments dans un ordre prévisible
                                                             (les attributs d'un élément dans un
                                            Document
                                                /
                                                             ordre non prévisible)


         PI                                                                     Element
<?xml version=“1.0”?>                                                            corpus




                                                   Element
                                                     text




       Element                    Element                    Element          Element
          p                          p                          p                p




        Text                                                  Text             Text
                        Element
                                            Text
                         name



                         Text                                                               87
• Tant que parmi les descendants le
  processeur ne trouve pas de templates à
  appliquer, il continue à descendre dans
  l’ordre enfant / frère, en imprimant les
  nœuds texte.

Si un template avec match="p" est
défini, le processeur l’applique,
sinon il descend au nœud texte,
l’imprime, et remonte au p suivant     Element
                                          p
                                                           Element
                                                              p




Idem : s’il n’existe pas de template   Text
pour name, passe aux nœuds enfants               Element
                                                  name
                                                                     88
   • Si un template correspond, le processeur
     l’exécute, et ne passe aux descendants que
     lorsqu’il est explicitement relancé avec
     l’instruction xsl:apply-templates

<xsl:template match="p">
    <p><xsl:apply-templates /></p>
</xsl:template>
Ce template est exécuté à chaque p rencontré. Une
                                                                    Element             Element
balise p est ouverte, l’analyse reprend dans la sous-                  p                   p
arborescence (d’autres templates peuvent être
exécutés), puis le p est fermé

<xsl:template match="name">                                          Text
    M. ***                                                                    Element
                                                                               name
</xsl:template>
Toutes les balises name et leur contenu sont remplacés par « M. *** ».                    89
               L’enchâssement
• Dans un template, l’ instructions, xsl:apply-
  templates a un effet spécial : elle relance la
  recherche de templates parmi les enfants.
  – Quand le processeur a fini de traiter les descendants, il
    reprend et termine l’exécution du template d'où il est parti
    du fait de l'instruction apply-templates
• Sinon, il ne rentre pas dans la sous-arborescence.
• Avec les xsl:apply-template les templates sont
  donc "enchâssés" autant de fois que nécessaire
  pendant l'exécution.
• xsl:template permet de traiter les éléments
  inclus, contrairement à value-of               90
                L'enchâssement (2)
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   1. Imprimé en premier
          version="1.0">
                                                   2. Passe à la
  <xsl:template match="/">                         descendance, alors que
          <html><body>                             le template n'est pas fini.
    <xsl:apply-templates />                        Imprime le texte contenu
          </body> </html>                          dans les éléments sauf p
  </xsl:template>
                                                   3. Tous les p sont traités
  <xsl:template match="p">
                                                   4. Quand la
    <item><xsl:value-of select="." /> </item>
                                                   descendance est traitée
  </xsl:template>
                                                   "remonte" de templates
                                                   appelant en templates
</xsl:stylesheet>
                                                   appelant et fini chacun.
                                                   Cette ligne est donc
                                                                         91
                                                   imprimée en tout dernier
Utilisation de xsl:apply-templates
 • On peut mettre plusieurs xsl:apply-templates dans
   le même template.


  <xsl:template match="/">
         <html><body>
                <h1>1. les ref</h1>
                <xsl:apply-templates select="//xptr">
                <h1>2. les id</h1>
                <xsl:apply-templates select="//xptr/@id">
         </body></html>
  </xsl:template>




                                                            92
apply-templates : utiliser @select
 @select permet de préciser au processeur où reprendre la
 recherche de templates

  <xsl:template match="/">
           <sous-corpus>
           <xsl:apply-templates select='teiCorpus.2//text/body//p'/>
           </sous-corpus>
    </xsl:template>
                                                  Ici on évite de recopier les
    <xsl:template match="p">                      header, front et back, en
                                                  passant directement aux p
      <item><xsl:value-of select="." /> </item>
    </xsl:template>



                                                                                 93
Voir les deux schémas suivants…
select indique où relancer
                                                                     <xsl:template match="/">
l'analyse dans l'arborescence.                                       …
Le processeur ne cherche pas                       Document          <apply-template select =„xx/xx//p'
de templates pour les                                  /
descendants de /, par exemple il
saute par-dessus un teiHeader.
                PI                                                                         Element
       <?xml version=“1.0”?>                                                                corpus




                                                          Element
                                                            text




              Element                    Element                    Element              Element
                 p                          p                          p                    p




               Text                                                  Text                 Text
                               Element
                                                   Text
                                name



                                Text                                                                      94
                                                    Pour chacun des fragments
                                                    désignés par select, la
                                                    recherche de templates et le
<xsl:template match=“p">                            parcours dans la sous-
                                                    arborescence reprend


       Element             Element          Element             Element
          p                   p                p                   p




       Text                                  Text                Text
                 Element
                                     Text
                  name



                  Text




                                                                                   95
• @select permet ici de descendre directement
  plus bas dans la sous-arborescence en
  "sautant" toute une partie.
• On peut aussi désigner un endroit qui n'est pas
  dans la sous arborescence, voire relancer
  l'analyse à la racine avec un select="/" qui
  fait boucler indéfiniment.
• Note : par défaut, un xsl:apply-templates
  contient donc un @select="node()" qui le fait
  sélectionner ses enfants
                                                96
        Supprimer les balises
• Une feuille de style contenant ce seul template
  recopie le document source en enlevant toutes
  les balises :

  <xsl:template match="/">
     <xsl:apply-templates />
  </xsl:template>

• Par défaut, dans tous les nœuds où il ne trouve
  pas de xsl:template qui s’applique, le
  processeur imprime le contenu pour les noeuds
  de type texte et passe aux enfants pour les
  autres types de nœuds.                          97
 select : exemple d'utilisation
• On veut recopier le texte du corpus sans
  balises, et sauter les header du corpus et
  des textes.
• Dans ce cas de figure, la majorité du corpus
  est recopié, et c'est seulement un tag dont le
  contenu est à exclure. La méthode la plus
  économique consiste donc à laisser le
  processeur recopier par défaut, et indiquer le
  tag à exclure.
                                            98
                           Méthode 1
• select permet de paramétrer le chemin du
  processeur pour exclure les headers
  <?xml version="1.0"?>
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            version="1.0">

  <xsl:template match="teiCorpus.2">
           <!-- on saute le header du corpus en passant directement aux TEI.2 -->
           <xsl:apply-templates select='//TEI.2'/>
   </xsl:template>

   <xsl:template match="TEI.2">
           <!-- dès qu'on arrive à un TEI.2, on fait sauter le header des TEI.2
                en passant au texte -->
           <xsl:apply-templates select='text'/>
   </xsl:template>
                                                                                    99
  </xsl:stylesheet>
                          Méthode 2
 • Plutôt que d'indiquer au processeur des chemins
   à parcourir qui excluent les headers, on peut
   modifier son action par défaut (recopier le texte)
   sur les nœuds à exclure :
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          version="1.0">

<xsl:template match="teiHeader">
         <!– le template ne contient rien : ni action, ni relance du
         processeur avec apply-templates. Le contenu est donc abandonné -->
</xsl:template>

</xsl:stylesheet>                                                         100
   La clef : les templates par défaut
• Pourquoi, par défaut, le processeurs descend dans
  l'arborescence et imprime les noeuds textes?
• Une feuille de style a deux templates par défaut ;
• Ces templates sont appliqués quand le processeur ne
  trouve pas dans la feuille de style un template
  correspondant au noeud traité
                                     Correspond à la racine (/) ou (|) à tout
<xsl:template match=“/ | *”>         element (*). Action = avancer le processeur
                                     aux enfants (incluant élément, attribut et
        <xsl:apply-templates/>
                                     noeud texte : apply-template à par défaut
</xsl:template>
                                     @select=“node()”), et leur appliquer les
                                     templates.
<xsl:template match=“text()”>
                                       Correspond à tout noeud texte.
        <xsl:value-of select=“.”/>     Action = imprimer son contenu
</xsl:template>                                                           101
        Quand plusieurs templates
          peuvent s’appliquer…
• pourquoi le processeur applique
  <xsl:template match="TEI.2">
  et non le template par défaut
  <xsl:template match="/ | *">,
  alors que les deux correspondent ?
• Le processeur applique le template le plus
  spécifique.
• On peut utiliser cette propriété pour prévoir un cas
  général et des cas particuliers :
  @match="p" : s’applique à tous les p sauf...
  @match="p[1]" s’applique à tous les aînés des fratries.
                                                       102
 Redéfinir les templates par défaut
• On peut redéfinir les templates par défaut
  pour modifier le comportement du
  processeur.
• Si on ajoute
   <xsl:template match="text()">
   </xsl:template>
  le processeur parcours toujours
  l'arborescence mais n'imprime plus les
  noeuds textes.
                                           103
     Exemple de modification des
        templates par défaut
• On veut extraire du corpus seulement le
  contenu des nœuds note.
• Dans ce cas de figure la majorité du corpus
  est à exclure, seulement un tag est à
  conserver.
• Comme dans l'exemple précédent on peut
  utiliser deux possibilités :
  – Indiquer le chemin qui mène aux nœuds voulus
  – Laisser le cheminement par défaut dans
    l'arborescence, mais modifier le comportement
    par défaut pour ne pas recopier les nœuds textes
                                                104
                        Méthode 1
• Laisser le comportement par défaut, mais
  utiliser @select pour mener directement
  sur les note
 <?xml version="1.0"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
           version="1.0">

 <xsl:template match="/">
          <xsl:apply-templates select="//note">
 </xsl:template>

 </xsl:stylesheet>

                                                                    105
                         Méthode 2
• On modifie le comportement par défaut : on
  laisse le cheminement dans l'arborescence,
  mais les nœuds textes ne sont plus recopiés,
  sauf pour le nœud voulu.

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

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

   <xsl:template match="note">
             <note><xsl:value-of select='.'/></note>
   </xsl:template>
                                                                      106
   </xsl:stylesheet>
            Pour résumer (1)
• Le processeur parcours l’arborescence, piloté
  par des templates, qui peuvent l'arrêter à des
  endroits précis, exécuter des instruction XSLT,
  et le relancer
• Quand il ne trouve pas de template à appliquer,
  le processeur parcours l'arborescence, relancé
  par un template par défaut, dans un ordre
  éléments enfants / éléments frères, et imprime le
  texte.
• A moins qu’un template capte le processeur
  dans l’arborescence et ne le relance pas, l’arbre
  est parcouru entièrement, et tous les nœuds
  textes sont répliqués.
                                                 107
             Pour résumer (2)
• Avec des templates on pilote le processeur :
  – En insérant des templates à des points avec match
  – En relançant ou non avec apply-templates
  – En sélectionnant des sous arbres avec @select
  – En utilisant ou modifiant les templates par défaut.
• L’ensemble de ces moyens d’action permet
  d'utiliser l'approche la plus économique pour
  décrire une transformation de l’arborescence
  source en une arborescence cible.
                                                  108
                      Exemple
• Conversion TEI -> Hyperbase
• Conversion TEI -> HTML
   – permet de lire le fichier à l'écran avec un
     navigateur internet, de l'ouvrir avec Microsoft
     Word pour l'imprimer ou le convertir dans le
     format Word.


Cf. fichiers joints


                                                   109
Grouper
 Extraire les valeurs différentes
• Comment produire une liste sans doublon
  des valeurs de @lang ?
  – Avec <xsl:for-each select="//@lang">
    la liste produite peut contenir plusieurs fois la
    même valeur.
• Comment regrouper les nœuds sur une
  valeur commune ?
  – Par exemple à partir de plusieurs tag
    correction (<corr resp="DC" date="12-
    06-2002">), les classer par correcteur sans
    les connaître à l'avance.
                                                    111
         Solution : xsl:key
• xsl:key déclare une variable dans
  laquelle des nœuds sont regroupés par
  "clefs".
• xsl:key a trois attributs obligatoires :
  – @name : donne un nom à la variable
  – @match : une expression XPath indiquant les
    nœuds à collecter
  – @use : une expression XPath indiquant quelle
    valeur utiliser pour grouper ces nœuds.

                                              112
<xsl:key                                On recherche les tags corr
      name="grouperParResp"             On les groupes selon la valeur
      match="//corr"                    de leur attribut @resp (le
      use="@resp"                       contexte de cette expression
/>                                      XPath est le nœud corr)

en se <corr sic='désaisissant'
resp='DB'>dessaisissant</corr> ... <corr sic='desine'
resp='DB'>dessine</corr> déjà les traits ... <corr
sic='l&apos;originial' resp='CF'>l'original</corr> ...
<corr sic='uotre' resp='CF'>notre</corr>

    Clefs                           Nœuds collectés

                   <corr sic='désaisissant'
     DB                                             <corr sic='desine'
                 resp='DB'>dessaisissant</
                                                resp='DB'>dessine</corr>
                            corr>


     CF          <corr sic='l&apos;originial'       <corr sic='uotre'
                 resp='CF'>l'original</corr>     resp='CF'>notre</corr>
                                                                          113
• L’élément key définit un groupe de nœud,
  lui attribue un nom et définit l’expression
  (la clef) qui permet de différencier les
  nœuds au sein de ce groupe.




                                            114
                          Utilisation
• Une fois créée une variable xsl:key peut être
  utilisée pour obtenir les nœuds associés à une clef.
• la fonction XPath key(nom_table, clef)
  retourne tous les nœuds associés à l'entrée clef
  dans la table nom_table
<xsl:for-each select="key(grouperParResp, 'DB')">
  Texte d'origine : <xsl:value-of select="@sic"/>
  Texte corrigé   : <xsl:value-of select="."/>
</xsl:for-each>

   Appliqué à l'exemple
                          Texte   d'origine   :   désaisissant
            précédent :   Texte   corrigé     :   dessaisissant
                          Texte   d'origine   :   desine
                          Texte   corrigé     :   dessine    115
   Trouver les valeurs uniques
• Avec la fonction key() on ne peut que retrouver
  les nœuds associés à une clef, on ne peut pas
  lister directement les clefs d'une variable
  xsl:key.
• Pour une liste de valeurs différentes, par
  exemple la liste des valeurs utilisées dans
  @lang, il faut utiliser une méthode détournée :
  – utiliser une expression qui extrait un élément de
    chaque groupe correspondant à une clef.
     • Par exemple ne prendre que les éléments dont l'index dans
       le groupe dont il fait parti est 1
     • Pour savoir si un nœud est le même que le premier retourné
       par un groupe , on peut comparer la valeur que retourne
       generate-id() qui retourne un identifiant unique constant
       pour chaque nœud.
                                                               116
                       Exemple
<xsl:key name="langues" match="//@lang" use="."/>

<xsl:for-each
     select="//@lang[generate-id(.)=
     generate-id(key(Langues', .)[1])]"> ...
•key(Langues', .) retourne le groupe des noeuds doublons
du noeud traité.
•key(Langues', .)[1] retourne le premier élément du groupe
•generate-id retourne un identifiant unique pour un noeud. L'id
du noeud contexte doit être le même que l'id du premier noeud du
groupe des noeuds doublons.
• On sélectionne uniquement le premier noeud de chaque groupe,
donc un noeud par groupe.                                   117
 • Cette méthode peut être utilisée avec un
   nœud différent entre match et use :
<xsl:key name="Langue" match="*[@lang]" use="@lang"/>
<table>
  <tr>
       <td>Langues</td>
       <td>Nombre d'éléments dans cette langue</td>
  </tr>
  <xsl:for-each select="//*[@lang and generate-id(.)=
                generate-id(key('Langue', @lang)[1])]">
  <tr>
    <td><xsl:value-of select="@lang" /></td>
    <td><xsl:value-of select="count(key('Langue',
@lang))"/>
  </td>
  </tr>
  </xsl:for-each>
</table>
                                                          118
• @use peut être n'importe quelle
  expression calculée. Par exemple on peut
  grouper les p en fonction du nombre de
  notes qu’ils contiennent
  – xsl:key name="pParNote"
    match="//p" use="count(note)«
• On peut imaginer maintenant de regarder
  pour chaque groupe la position moyenne
  en début ou fin de texte, etc.

                                         119
Ajout d’information,
Editer le corpus source
• Jusqu’ici XSLT était utilisé pour extraire des
  données, pas pour éditer le corpus source.
• XSLT impose de nombreuses limites à une
  utilisation pour ajouter de l’informations : il
  est difficile de « recopier » à l’identique.
• L’édition d’un corpus avec XSLT ne peut
  donc se faire que sur des corpus très
  normalisés.
                                              121
   Recopier à l’identique : copy-of
•A La différence de value-of, copy-of retourne la
représentation textuelle de l’arborescence.
•xsl:copy-of ne permet pas d’ajouter de l’information, mais
illustre les limites de la duplication à identique, par exemple la
perte du prolog (<!DOCTYPE...) que XSLT ne prend pas en
charge
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:template match="/">
  <xsl:copy-of select="." />
</xsl:template>

</xsl:stylesheet>

                                                                     122
                      xsl:copy
En utilisant récursivement la fonction copy dans un template, on peut
obtenir cette duplication et définir des templates pour ajouter des
modifications
<xsl:template match="node() | @*">
  <xsl:copy>
   <xsl:apply-templates
             select="node() | @*"/>
  </xsl:copy>
</xsl:template>

<!-- Les templates de modification : -->
<xsl:template match="xptr[not(@id)]">
  <!-- on supprime les xptr sans id. -->
</xsl:template>

                                                                   123
xsl:element et xsl:attribut
• Pour générer des balises et des attributs
  on peut utiliser les éléments
  xsl:element et xsl:attribut qui
  permettent de les construire pas à pas.
• Les deux fonctions prennent un attribut
  name, qui sera le nom de la balise ou de
  l’attribut, et le texte contenu dans
  xsl:element et xsl:attribut
  deviendra le texte de l’élément ou la
  valeur créé.
                                              124
 Exemple 1 : déplacer un élément
• Dans un corpus les notes sont regroupées à la
  fin du document. Des éléments ptr ont permis
  d’enregistrer l’endroit des appels de note ; leur
  attribut @target permet de les associer à la note
  dont l’attribut @id correspond
• Le but est de remonter les notes, conformément
  aux prescription TEI, directement à leur point
  d’insertion dans le texte et supprimer les
  pointeurs ptr.

                                                 125
<xsl:template match="node() | @*">
  <xsl:copy>
   <xsl:apply-templates
                select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="ptr">
   <xsl:variable name="id" select="@target" />
   <xsl:element name="note">
    <xsl:for-each select="./ancestor::text/back/note[@id=$id]/@*">
      <xsl:attribute name="{name(.)}">
        <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:for-each>
   <xsl:value-of select=".//ancestor::text/back/note[@id=$id]"/>
  </xsl:element>
</xsl:template>

<xsl:template match="note">
</xsl:template>

</xsl:template>




 Cf. ci-joint "ajout.xsl"                                            126
Conclusion
                   Limites d'XSLT
• Délicat pour l'ajout d'annotation au corpus
   – Délicat de contrôler complètement la réécriture
• Lourd et insuffisant pour la manipulation des chaînes de
  caractère (les nœuds texte)
   – Prévu pour la manipulation de la structure, de l'encodage plus
     que du contenu des nœuds textes
• Inutilisable avec de très gros documents
   – Prévoir dix fois la taille du fichier en mémoire vive.
• Ces limites sont dues à l'approche "arborescente" :
  XSLT permet de manipuler une arborescence en
  mémoire.
   – Une autre représentation du contenu, dite "séquentielle" permet
     plus de précision et n’est pas limité par la taille du document,
     mais demande l’utilisation d’un langage de programmation.
                                                                      128
Efficacité comme langage de requête
Deux stratégies à cumuler : à dominante
  procédurale ou déclarative.
Economie et plasticité grâce à l’utilisation de
  templates et templates par défaut.
Adapté à l’extraction d’information, la projection de
  sous-corpus ou la conversion vers d’autres
  formats.
La version 2 de XSLT apportera des améliorations
  (expressions régulières, typage, regroupement),
  sans changer cette dominante « extraction »,
  plus que « édition », dans la « transformation »
                                                   129

								
To top