La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

XSLT : XML Stylesheet Language Transformation

Présentations similaires


Présentation au sujet: "XSLT : XML Stylesheet Language Transformation"— Transcription de la présentation:

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

2 Introduction

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

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

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

6 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

7 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

8 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

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

10 Une première feuille de style
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl=" <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

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

12 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

13 Extraire des informations

14 Extraire le texte contenu dans une balise
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl=" <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>

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

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

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

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

19 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

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

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

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

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

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

25 <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl=" <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>

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

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

28 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

29 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

30 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 = '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

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

32 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 = '1']"> <h1><xsl:value-of select="./head"/></h1> <xsl:for-each = '2']"> <h2><xsl:value-of select="./head"/></h2> <xsl:for-each = '3']"> <h3><xsl:value-of select="./head"/></h3> </xsl:for-each> <hr />

33 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).

34 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

35 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= " <xsl:output encoding="iso " mode="html" />

36 Résumé XPath XPath permet d’écrire des « chemins XML » mais également d’utiliser des fonctions et des opérateurs.

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

38 (1) les étapes Le slash indique la relation parent / enfant
Un double slash indique la relation parent / descendants (à toute profondeur dans la hiérarchie). 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.

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

40 (2) : les node tests Chaque étape comprend un node test
Le nœud cherché peut être une balise, un attribut ou un nœud texte (text()) Existent également des valeurs génériques : * (tout (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.

41 Exemples //*[@rend = 'italics']/text() teiCorpus.2/TEI.2[1]/teiHeader
//p[../liste] : 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… Ne retourne rien : il n'y a pas de nœud texte descendant d'un attribut. retourne déjà la "valeur")

42 (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. sélectionne les div ayant un 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 ».

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

44 Exemples <xsl:for-each = ‘italics’]"> <!-- tous les tags hi avec un attribut rend = italics --> </xsl:for-each> <xsl:for-each <!-- 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 -->

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

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

47 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

48 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

49 <?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 Text lightgrey Enfant Text Jeff Descendants

50 <?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 Text 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

51 <?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 Text Text lightgrey À partir de FitnessCenter, descendant::* sélectionnera tous les descendants, c’est à dire : - Member - Name - Phone, etc

52 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

53 Exemples

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

55 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 : < > = <= >= != < > = <= >= !=

56 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 ou 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"

57 Expression de conditions Opération sur les chaînes

58 xsl:if <xsl:if test="expression XPath"/>
Permet de filtrer ou de choisir entre différentes possibilités. Si l’expression XPath 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>

59 Exemples de xsl:if <xsl:for-each select="name">
<xsl:if <xsl:value-of select='.'> </xsl:if> </xsl:for-each> Ici c'est l'équivalent de : <xsl:for-each <xsl:value-of select='.'> </xsl:for-each>

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

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

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

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

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

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

66 Fonctions sur des chaînes
substring-before(chaîne, pattern) substring-after(chaîne, pattern) substring(chaîne, index, len?) ex: substring(‘ ’, 2, 5) => ‘23456’ string-length(chaîne) ex: string-length(‘ ’) => 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 >

67 Exemple d'utilisation : on veut les éléments en italique, avec la valeur IT dans l'attribut @rend.
peut également contenir "IT BO" ou "BO IT" pour marquer italique + gras, etc. On ne les extraira pas si on utilise = 'IT']", qui recherchera avec comme valeur exactement IT. contains permet ici de récupérer tous les italiques 'IT')]"

68 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

69 Quantifier

70 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= = 'intro'])"/> = 'en'])"/> 'exemple'])"/>

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

72 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 pour lui donner un : 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 :

73 Stocker une valeur calculée
<xsl:variable name="nbrDiv" select="count(//div)" /> <xsl:variable name="nbrDiv1" = '1'])" /> <xsl:variable name="nbrDiv2" = '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

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

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

76 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

77 <xsl:template match="/">
<xsl:variable name="nbrDiv" select="count(//div)" /> <xsl:variable name="nbrDiv1" = '1'])" /> <xsl:variable name="nbrDiv2" = '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

78 Utiliser des templates

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

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

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

82 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 @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.

83 Comment utiliser les templates ?
Il suffit, pour l’élément que l’on veut traiter, de lui faire un élément template avec qui lui correspond. @match peut correspondre à tout nœud : élément, attribut 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>

84 Exemple : mettre un titre HTML à chaque texte
<xsl:stylesheet version="1.0" xmlns:xsl=" > <xsl:template match="TEI.2"> <h1>nouveau texte : <xsl:value-of select=".//titleStmt/title" /> </h1> <xsl:apply-templates /> </xsl:template> </xsl:stylesheet>

85 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

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

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

88 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

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

90 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

91 L'enchâssement (2) <?xml version="1.0"?> <xsl:stylesheet
xmlns:xsl=" 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

92 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 </body></html> </xsl:template>

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

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

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

96 @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 qui le fait sélectionner ses enfants

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

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

99 Méthode 1 select permet de paramétrer le chemin du processeur pour exclure les headers <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl=" 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>

100 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=" 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>

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

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

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

104 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

105 Méthode 1 Laisser le comportement par défaut, mais pour mener directement sur les note <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl=" version="1.0"> <xsl:template match="/"> <xsl:apply-templates select="//note"> </xsl:template> </xsl:stylesheet>

106 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=" version="1.0"> <xsl:template match="text()"> </xsl:template> <xsl:template match="note"> <note><xsl:value-of select='.'/></note> </xsl:stylesheet>

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

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

109 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

110 Grouper

111 Extraire les valeurs différentes
Comment produire une liste sans doublon des valeurs ? Avec <xsl:for-each 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=" ">), les classer par correcteur sans les connaître à l'avance.

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

113 On recherche les tags corr
<xsl:key name="grouperParResp" match="//corr" /> On les groupes selon la valeur de leur (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

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

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

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

117 Exemple <xsl:key name="langues" match="//@lang" use="."/>
<xsl:for-each 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.

118 Cette méthode peut être utilisée avec un nœud différent entre match et use :
<xsl:key name="Langue" <table> <tr> <td>Langues</td> <td>Nombre d'éléments dans cette langue</td> </tr> <xsl:for-each and generate-id(.)= <td><xsl:value-of /></td> <td><xsl:value-of </td> </xsl:for-each> </table>

119 @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.

120 Ajout d’information, Editer le corpus source

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

122 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=" <xsl:template match="/"> <xsl:copy-of select="." /> </xsl:template> </xsl:stylesheet>

123 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 <!-- on supprime les xptr sans id. -->

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

125 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 permet de les associer à la note dont 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.

126 Cf. ci-joint "ajout.xsl" <xsl:template match="node() | @*">
<xsl:copy> <xsl:apply-templates | node()"/> </xsl:copy> </xsl:template> <xsl:template match="ptr"> <xsl:variable name="id" /> <xsl:element name="note"> <xsl:for-each <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:value-of </xsl:element> <xsl:template match="note"> Cf. ci-joint "ajout.xsl"

127 Conclusion

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

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


Télécharger ppt "XSLT : XML Stylesheet Language Transformation"

Présentations similaires


Annonces Google