XSLT : XML Stylesheet Language Transformation

Slides:



Advertisements
Présentations similaires
Mais vous comprenez qu’il s’agit d’une « tromperie ».
Advertisements

ORTHOGRAM PM 3 ou 4 Ecrire: « a » ou « à » Référentiel page 6
Additions soustractions
Distance inter-locuteur
1 Plus loin dans lutilisation de Windows Vista ©Yves Roger Cornil - 2 août
Calcul mental Calcul mental Année scolaire Classe de …
1 3.Langage XSL = XSLT + XSL-FO transformationFormatage.
Fonctions & procédures
Transformation de documents XML
DTD Sylvain Salvati
Les numéros 70 –
Les numéros
Cours MIAGE Henry Boccon-Gibod 1 XML, langage de structuration documentaire Langage de transformation et langage d'interrogation.
le langage les éléments
Les fonctions de XPath et XSLT
Domaines nominaux XSLT
Tutoriel XSLT F. Sajous ERSS – 01/04/2005.
Algorithme et structure de données
LES TRIANGLES 1. Définitions 2. Constructions 3. Propriétés.
Manipulation d’XML avec XSL
Chap. 1 Structures séquentielles : listes linéaires
ESIEE Paris © Denis BUREAU I N Initiation à la programmation avec le langage Java.
Technologies et pédagogie actives en FGA. Plan de latelier 1.Introduction 2.Les technologies en éducation 3.iPads 4.TNI 5.Ordinateurs portables 6.Téléphones.
Révision (p. 130, texte) Nombres (1-100).
La législation formation, les aides des pouvoirs publics
Cours XSLT/XPath - Yves Laborde
La méthodologie………………………………………………………….. p3 Les résultats
Les requêtes La Requête est une méthode pour afficher les enregistrements qui répondent à des conditions spécifiques. La requête est donc un filtre.
Récursivité.
Le soccer & les turbans Sondage mené par lAssociation détudes canadiennes 14 juin 2013.
Les structures de données arborescentes
Présentation générale
Xml/xslt : Extensible Stylesheet Language Transformation réalisé par: saÏd NAÏM.
Les nombres.
Fierté envers les symboles et institutions canadiens Jack Jedwab Association détudes canadiennes 26 novembre 2012.
Tableaux de distributions
Tableaux de distributions
Introduction à la structuration des documents: les techniques M2: Gestion des connaissances.
Notions sur le XML Réfs : manuel p 149. Introduction Le XML (eXtensible Markup Language) est un standard d'échange de données. Il fait partie comme le.
Logiciel gratuit à télécharger à cette adresse :
Les chiffres & les nombres
Xpath XML Path language par Yves Bekkers
XSLT Langage de transformation darbre par Yves Bekkers.
Année universitaire Réalisé par: Dr. Aymen Ayari Cours Réseaux étendus LATRI 3 1.
Chapitre 9 Les sous-programmes.
MAGIE Réalisé par Mons. RITTER J-P Le 24 octobre 2004.
Aire d’une figure par encadrement
Les fondements constitutionnels
MAGIE Réalisé par Mons. RITTER J-P Le 24 octobre 2004.
Mise en forme en Mathématiques
Animateur : Med HAIJOUBI
Le Langage XML Belkhir Abdelkader Laboratoire LSI USTHB
1/65 微距摄影 美丽的微距摄影 Encore une belle leçon de Macrophotographies venant du Soleil Levant Louis.
Les outils de base : XPath, XSL, XLink, XForms
Certains droits réservés pour plus d’infos, cliquer sur l’icône.
XSL eXtensible Stylesheet Language Historique 1999: XSLT 1.0 et XPATH 1.0 : versions supportées par la plupart des outils depuis février 2007 XSLT 2.0.
Suites numériques Définitions.
Annexe Résultats provinciaux comparés à la moyenne canadienne
Le langage XML.
Chapitre 3 :Algèbre de Boole
La formation des maîtres et la manifestation de la compétence professionnelle à intégrer les technologies de l'information et des communications (TIC)
XPath XML Path UP Web Année universitaire
Introduction à l’informatique en gestion 1 Plan de la leçon Compagnon office Sections et Mise en page En-têtes et pieds de page Notes de bas.
Les balises HTML et les objets JavaScript correspondants Objet document L'objet document est important dans la mesure ou il contient tous les objets du.
Programmation Web : Introduction à XML
Technologies web et web sémantique TP3 - XML. XML eXtensible Markup Language (langage extensible de balisage) – Caractéristiques: méta-langage = un langage.
 Syntaxe du langage PHP
Module : Langage XML (21h)
XSLT. Les documents XML peuvent avoir dans leur prologue une instruction de traitement xml-stylesheet. Cette instruction de traitement indique au navigateur.
Transcription de la présentation:

XSLT : XML Stylesheet Language Transformation Une introduction à XSLT pour l'analyse de corpus Sylvain Loiseau <sylvain.loiseau@u-paris10.fr>

Introduction

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

« 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

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.

Le processeur transforme le document en un autre Feuille de style XSLT : règles de la transformation teiHeader fileDesc Text title Racine Document XML source Document XML produit truc machin Transformation Text Processeur

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

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

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.

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

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 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

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>

L'instruction xsl:value-of <xsl:value-of select="/TEI.2/.../title"/> Remplacer cette instruction par le texte… … trouvée à cet endroit La valeur de l'attribut select est une expression XPath : elle désigne un endroit du document où aller chercher le texte.

<?xml version=“1.0”?> "/TEI.2/teiHeader/fileDesc/titleStmt/title" Document / PI <?xml version=“1.0”?> Element TEI.2 teiHeader … fileDesc Text title

<?xml version=“1.0”?> <xsl:value-of select="/corpus/text/p/name"/> Document / PI <?xml version=“1.0”?> Element corpus Bien qu’il y ait plusieurs p, un seul chemin satisfait entièrement à l’expression (un seul p a un élément name) Element text Element p Element p Element p Element p Text Text Text Element name Text Text

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…)

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

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.

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>

<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>

<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 p Element p Element p Element p Text Text Text Element name Text Text

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.

<?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"/> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

… … … A chaque itération on applique une nouvelle recherche XPath <xsl:for-each select="/teiCorpus.2/TEI.2"> Element … Element TEI.2 Element TEI.2 Element TEI.2 Element TEI.2 … … … A chaque itération on applique une nouvelle recherche XPath Element … Element … Element title Element … Text <xsl:value-of select="teiHeader/fileDesc/titleStmt/title"/>

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"

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

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

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 commence pas par « / » : text est recherché parmi les enfants du nœud contexte (le TEI.2 traité) <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> <hr /> Par rapport au nouveau contexte (div), on désigne le premier enfant head

select="text/body/div[@type = '1']" Ce qui est entre crochets est un prédicat : permet de filtrer les éléments sélectionnés. @ permet de désigner un attribut. 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"/>

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> <hr />

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 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> Premier titre Second Titre Etc

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" />

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"

(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.

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.

(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.

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 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 ».

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].

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 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 select="//TEI.2[1]/text/p[position() != last())]"> <!-- autre notation --> <xsl:for-each select="//TEI.2[1]/text/p[position() > 1]"> <!-- tous les p sauf le premier -->

<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 p Element p Element p Element p Text Text Text Element name id='p5' n='8' Text

(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 :

XML, une histoire de famille Document / PI <?xml version=“1.0”?> Element corpus Ancêtres Parent Element text Frêres Element p Element p Element p Element p Text Text Text Element name Text Enfants Descendants Text

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" Select="./ancestor::TEI.2/teiHeader Following-sibling::node() | preceding-sibling::node() Recherche le premier div parmi les ascendants Remonte au TEI.2 ascendant, puis descend à son enfant direct teiHeader Sélectionne n’importe quel type de nœud descendant du même père, soit à droite sinon à gauche

<?xml version=“1.0”?> Document / PI <?xml version=“1.0”?> Element FitnessCenter Ancêtres Element Member Parent Element Name Element Phone Element Phone Element FavoriteColor Frêre précédent Frêres Suivants Text Jeff Element Name Text 555-4321 Text lightgrey Enfant Text Jeff Descendants

<?xml version=“1.0”?> Document / PI <?xml version=“1.0”?> Element FitnessCenter Element Member ancêtre Element Name Element Phone Element Phone Element FavoriteColor Frêre précédent Frêres suivants Text Jeff Text 555-1234 Text 555-4321 Text lightgrey ancestor::* sélectionnera tous les ancêtres, c’est à dire : - Member - FitnessCenter preceding-sibling::* sélectionnera tous les frêres à gauche, c’est à dire : - Name following-sibling::* sélectionnera tous les frêres à droite, c’est à dire : - Phone - FavoriteColor

<?xml version=“1.0”?> Document / PI <?xml version=“1.0”?> Element FitnessCenter descendants Element Member Element Name Element Phone Element Phone Element FavoriteColor Text Jeff Text 555-1234 Text 555-4321 Text lightgrey À partir de FitnessCenter, descendant::* sélectionnera tous les descendants, c’est à dire : - Member - Name - 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

Exemples

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::.

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 < et > pour satisfaire aux contraintes XML. Pour exprimer : Noter : < > = <= >= != < > = <= >= !=

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"

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>

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>

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.

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:otherwise> </xsl:otherwise> </xsl:choose>

... <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:text>), </xsl:text> <xsl:if> <xsl:if select=".//title"> <i><xsl:value-of select="title" /></i> </p>

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)

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"

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:

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 -->

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')]"

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

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'])"/> "count(//*[@lang = 'en'])"/> "count(//div/p[1]/*[@ana= 'exemple'])"/>

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 ?

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 Hello World Valeur de la variable :

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 : Évite de recalculer plusieurs fois count(//div) Code plus lisible

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.

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.

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

<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"> <xsl:with-param name="Nbr1" select="$nbrDiv1"/> <xsl:with-param name="Nbr2" select="$nbrDiv"/> </xsl:call-template> Pourcentage de section de niveau 2 : <!-- etc. --> <!-- calcul des pourcentages --> <xsl:template name="calculPourcentage"> <xsl:param name="Nbr1"/> <xsl:param name="Nbr2"/> <xsl:value-of select="($Nbr1 * 100) div $Nbr2"/> </xsl:template> Appel d’un template xsl:with-param permet de transmettre les arguments xsl:param permet de nommer les arguments reçus

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…

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.

Plutôt que de décrire des opérations, on dessine un nouvel arbre en indiquant seulement les points à modifier de l'arbre existant.

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.

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>

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>

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

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.

<?xml version=“1.0”?> Le processeur parcours les éléments dans un ordre prévisible (les attributs d'un élément dans un ordre non prévisible) Document / PI <?xml version=“1.0”?> Element corpus Element text Element p Element p Element p Element p Text Text Text Element name Text Text

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 pour name, passe aux nœuds enfants Text Element name

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 balise p est ouverte, l’analyse reprend dans la sous-arborescence (d’autres templates peuvent être exécutés), puis le p est fermé Element p Element p <xsl:template match="name"> M. *** </xsl:template> Text Element name Toutes les balises name et leur contenu sont remplacés par « M. *** ».

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

L'enchâssement (2) <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <html><body> <xsl:apply-templates /> </body> </html> </xsl:template> <xsl:template match="p"> <item><xsl:value-of select="." /> </item> </xsl:stylesheet> 1. Imprimé en premier 2. Passe à la descendance, alors que le template n'est pas fini. Imprime le texte contenu dans les éléments sauf p 3. Tous les p sont traités 4. Quand la descendance est traitée "remonte" de templates appelant en templates appelant et fini chacun. Cette ligne est donc 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>

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> <xsl:template match="p"> <item><xsl:value-of select="." /> </item> Ici on évite de recopier les header, front et back, en passant directement aux p Voir les deux schémas suivants…

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

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

@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

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.

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.

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: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>

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 element (*). Action = avancer le processeur aux enfants (incluant élément, attribut et noeud texte : apply-template à par défaut @select=“node()”), et leur appliquer les templates. <xsl:template match=“/ | *”> <xsl:apply-templates/> </xsl:template> <xsl:template match=“text()”> <xsl:value-of select=“.”/> </xsl:template> Correspond à tout noeud texte. Action = imprimer son contenu

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.

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.

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

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>

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: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.

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.

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

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.

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.

On recherche les tags corr <xsl:key name="grouperParResp" match="//corr" use="@resp" /> On les groupes selon la valeur de leur attribut @resp (le 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> DB CF <corr sic='désaisissant' resp='DB'>dessaisissant</corr> <corr sic='desine' resp='DB'>dessine</corr> <corr sic='l&apos;originial' resp='CF'>l'original</corr> <corr sic='uotre' resp='CF'>notre</corr> Clefs Nœuds collectés

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.

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> Texte d'origine : désaisissant Texte corrigé : dessaisissant Texte d'origine : desine Texte corrigé : dessine Appliqué à l'exemple précédent :

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.

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.

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])]"> <td><xsl:value-of select="@lang" /></td> <td><xsl:value-of select="count(key('Langue', @lang))"/> </td> </xsl:for-each> </table>

@use peut être n'importe quelle expression calculée @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.

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.

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>

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: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éé.

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.

Cf. ci-joint "ajout.xsl" <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 match="note"> Cf. ci-joint "ajout.xsl"

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.

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 »