View
112
Download
2
Category
Preview:
Citation preview
1
Introduction à XSLT - cours 4
Éric Laporte
Institut Gaspard-Monge
Université Paris-Est Marne-la-Vallée
2
Sommaire
Regrouper des entrées4
Introduire des références 12Produire un index
22Extraire des informations d'un document mal structuré 37Rendre explicite une structure implicite 44Produire plusieurs documents en même temps 52Analyser du texte 57
3
4. Objectifs5. Grouper par albums (1/4)6. Résultat7. Grouper par albums (2/4)8. Grouper par albums (3/4)9. Grouper par albums (4/4)10. Résultat11. Paramètres du script XSLT (1/2)12. Paramètres du script XSLT (2/2)13. Introduire des références à d'autres entrées (1/5)14. Résultat15. Introduire des références à d'autres entrées (2/5)16. Introduire des références à d'autres entrées (3/5)17. Introduire des références à d'autres entrées (4/5)18. Introduire des références à d'autres entrées (5/5)19. Variante avec identifiants (1/3)20. Variante avec identifiants (2/3)21. Résultat22. Variante avec identifiants (3/3)23. Index des horaires de métro (1/7)24. Index des horaires de métro (2/7)25. Index des horaires de métro (3/7)26. Index des horaires de métro (4/7)27. Index des horaires de métro (5/7)28. Index des horaires de métro (6/7)29. Index des horaires de métro (7/7)
30. Expressions relatives31. Expressions relatives32. Axes Xpath (1/6)33. Axes (2/6)34. Axes (3/6)35. Axes (4/6)36. Axes (5/6)37. Axes (6/6)38. Extraction à partir d'un document mal structuré (1/7)39. Extraction à partir d'un document mal structuré (2/7)40. Extraction à partir d'un document mal structuré (3/7)41. Extraction à partir d'un document mal structuré (4/7)42. Extraction à partir d'un document mal structuré (5/7)43. Extraction à partir d'un document mal structuré (6/7)44. Extraction à partir d'un document mal structuré (7/7)45. Donner une structure à un document "aplati" (1/7)46. Donner une structure à un document "aplati" (2/7)47. Donner une structure à un document "aplati" (3/7)48. Donner une structure à un document "aplati" (4/7)49. Donner une structure à un document "aplati" (5/7)50. Donner une structure à un document "aplati" (6/7)51. Donner une structure à un document "aplati" (7/7)52. Résultat53. Produire plusieurs documents (1/3)54. Produire plusieurs documents (2/3)55. Produire plusieurs documents (3/3)56. Résultat : l'index57. Résultat : le catalogue58. Analyser du texte (1/2)59. Analyser du texte (2/2)
4
Objectifs
Réorganiser la structure d'un document XMLCertains documents sont mal structurés (récupérés à
partir de documents plats)Certains documents sont conçus pour un usage puis
utilisés pour autre choseAjouter des informations redondantes (exemple : un
index alphabétique)
5
Grouper par albums (1/4)
Regrouper les pistes qui appartiennent à un même album
<xsl:template match="Tracks"> <xsl:for-each-group select="Track" group-by="Album"> <Album title="{current-grouping-key()}"> <xsl:apply-templates select="current-group()"/> </Album> </xsl:for-each-group> </xsl:template> <xsl:template match="Track"> <xsl:copy> <xsl:apply-templates select="*[name()!='Album']"/> </xsl:copy> </xsl:template>
6
Résultat
<?xml version="1.0" encoding="ISO-8859-1"?><iTunes> <Major_Version>1</Major_Version> <Minor_Version>1</Minor_Version> <Application_Version>4.6</Application_Version> <Music_Folder>file://localhost/C:/My%20Music/</Music_Folder> <Library_Persistent_ID>B2BF2C09D305D49C</Library_Persistent_ID> <Album title="american beauty soundtrack"> <Track> <Track_ID>37</Track_ID> <Name>American Beauty - Theme</Name> <Artist>Air</Artist> <Kind>MPEG audio file</Kind> <Size>3948579</Size> <Total_Time>197407</Total_Time>
7
Grouper par albums (2/4)
select spécifie les noeuds à grouper
group-by spécifie la clé de groupement : expression évaluée à partir de chacun des noeuds à grouper, puis convertie en valeur textuelle
Si un noeud à grouper a plusieurs clés, il figurera dans plusieurs groupes
S'il n'a pas de clé, il ne figurera dans aucun groupe
<xsl:for-each-group select="Track" group-by="Album"> <Album title="{current-grouping-key()}"> <xsl:apply-templates select="current-group()"/> </Album> </xsl:for-each-group>
8
Grouper par albums (3/4)
Le contenu de <xsl:for-each-group> est exécuté une fois par groupe
current-grouping-key() contient la clé courante
current-group() contient les noeuds du groupe courant
Le noeud courant est le premier noeud du groupe courantLa liste de noeuds courante contient le premier noeud de chaque
groupe
<xsl:for-each-group select="Track" group-by="Album"> <Album title="{current-grouping-key()}"> <xsl:apply-templates select="current-group()"/> </Album> </xsl:for-each-group>
9
Grouper par albums (4/4)
Si <xsl:for-each-group> contient <xsl:sort>, cela classe les groupes les uns par rapport aux autres
<xsl:sort> est exécuté une fois pour tous les groupes
Les instructions qui le suivent au même niveau sont exécutées une fois par groupe
Le noeud contexte dans le <xsl:sort> est le premier noeud de chaque groupe
<xsl:for-each-group select="Track" group-by="Album"> <xsl:sort select="current-grouping-key()" lang='fr'/> <Album title="{current-grouping-key()}"> <xsl:apply-templates select="current-group()"/> </Album> </xsl:for-each-group>
10
Résultat
<?xml version="1.0" encoding="ISO-8859-1"?><iTunes> <Major_Version>1</Major_Version> <Minor_Version>1</Minor_Version> <Application_Version>4.6</Application_Version> <Music_Folder>file://localhost/C:/My%20Music/</Music_Folder> <Library_Persistent_ID>B2BF2C09D305D49C</Library_Persistent_ID> <Album title="Absolute Reggae 2"> <Track> <Track_ID>61</Track_ID> <Name>Rendez-Vouz</Name> <Artist>Alpha Blondy</Artist> <Genre>Pop</Genre> <Kind>MPEG audio file</Kind> <Size>3380129</Size> <Total_Time>211200</Total_Time>
11
Paramètres du script XSLT (1/2)
Paramétrer l'ordre alphabétique en fonction de la langue
<xsl:strip-space elements="*"/> <xsl:param name="lang" select="'fr'"/>(...) <xsl:template match="Tracks"> <xsl:for-each-group select="Track" group-by="Album"> <xsl:sort select="current-grouping-key()" lang='$lang'/> <Album title="{current-grouping-key()}"> <xsl:apply-templates select="current-group()"/> </Album> </xsl:for-each-group> </xsl:template>
12
Paramètres du script XSLT (2/2)
Déclaration en-dehors des règles
L'attribut select (facultatif) donne la valeur par défaut
Ligne de commande avec Saxon sous Windows
> java -jar saxon8.jar -o par-album-param.xml iTunes.xml par-album-param.xsl lang=fr
<xsl:strip-space elements="*"/> <xsl:param name="lang" select="'fr'"/> <xsl:template match="Tracks"> <xsl:for-each-group select="Track" group-by="Album"> <xsl:sort select="current-grouping-key()" lang='$lang'/>
13
Introduire des référencesà d'autres entrées (1/5)
À la fin d'une entrée, ajouter des références aux autres plantes qui ont le même nom scientifique
<xsl:template match="jr:PLANT"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> <xsl:for-each select="//jr:PLANT [jr:BOTANICAL=current()/jr:BOTANICAL] [not(. is current())]"> <seeAlso> <xsl:value-of select="jr:COMMON"/> </seeAlso> </xsl:for-each> </xsl:copy> </xsl:template>
14
Résultat <PLANT id="3"> <COMMON>Marsh Marigold</COMMON> <BOTANICAL> <GENUS>Caltha</GENUS> <SPECIES>palustris</SPECIES> </BOTANICAL> <ZONE>4</ZONE> <LIGHT>Mostly Sunny</LIGHT> <PRICE unit="euro">6.81</PRICE> <AVAILABILITY>051799</AVAILABILITY> <seeAlso xmlns:jr="http://igm.univ-mlv.fr/~laporte/jardinerie">Cowslip</seeAlso> </PLANT> <PLANT id="4"> <COMMON>Cowslip</COMMON> <BOTANICAL> <GENUS>Caltha</GENUS> <SPECIES>palustris</SPECIES> </BOTANICAL>
15
Introduire des référencesà d'autres entrées (2/5)
À chaque entrée, on parcourt toutes les autres...2e solution : dans le document source, on indexe les entrées par les noms
scientifiques
<xsl:strip-space elements="*"/> <xsl:key name="botanical-to-plant" match="jr:PLANT" use="jr:BOTANICAL"/>(...) <xsl:variable name="meme-nom" select="key('botanical-to-plant', jr:BOTANICAL)"/> <xsl:for-each select="$meme-nom[not(. is current())]"> <seeAlso> <xsl:value-of select="jr:COMMON"/> </seeAlso> </xsl:for-each>
16
Introduire des référencesà d'autres entrées (3/5)
CATALOG
PLANT
BOTANICALCOMMON
BloodrootSanguinaria Canadensis
PLANT
...
ZONE LIGHT
4Mostly Shady
...
noeud à indexer
clé d'indexation
<xsl:strip-space elements="*"/> <xsl:key name="botanical-to-plant" match="jr:PLANT" use="jr:BOTANICAL"/>
17
Introduire des référencesà d'autres entrées (4/5)
CATALOG
PLANT
BOTANICALCOMMON
BloodrootSanguinaria Canadensis
PLANT
...
ZONE LIGHT
4Mostly Shady
...
noeud indexé
clé d'indexation
<xsl:variable name="meme-nom" select="key('botanical-to-plant', jr:BOTANICAL)"/>
18
Introduire des référencesà d'autres entrées (5/5)
<xsl:key name="botanical-to-plant" match="jr:PLANT" use="jr:BOTANICAL"/>Spécification des noeuds à indexer (match)Fonctionne comme dans <xsl:template match="...">Spécification des clés d'indexation (use)Expression Xpath évaluée à partir du noeud à indexerConvertie en liste de chaîne de caractères
<xsl:variable name="meme-nom" select="key('botanical-to-plant', jr:BOTANICAL)"/>Renvoie la liste des noeuds indexés par la cléUne clé peut indexer plusieurs noeuds
19
Variante avec identifiants (1/3)
Utiliser les identifiants d'entrées pour les références
<?xml version="1.0" encoding="ISO-8859-1"?><!-- plant_catalog_jr.xml --><CATALOG xmlns="http://igm.univ-mlv.fr/~laporte/jardinerie"> <PLANT id="1"> <COMMON>Bloodroot</COMMON> <BOTANICAL> <GENUS>Sanguinaria</GENUS> <SPECIES>canadensis</SPECIES> </BOTANICAL> <ZONE>4</ZONE> <LIGHT>Mostly Shady</LIGHT> <PRICE unit="euro">2.44</PRICE> <AVAILABILITY>031599</AVAILABILITY> </PLANT> <PLANT id="2">
20
Variante avec identifiants (2/3)
<xsl:strip-space elements="*"/> <xsl:key name="botanical-to-plant" match="jr:PLANT" use="jr:BOTANICAL"/>(...) <xsl:template match="jr:BOTANICAL"> <xsl:copy> <xsl:variable name="meme-nom" select="key('botanical-to-plant', .) [not(jr:BOTANICAL is current())]"/> <xsl:if test="$meme-nom"> <xsl:attribute name="same-name" select="$meme-nom/@id"/> </xsl:if> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template>
21
Résultat <PLANT id="16"> <COMMON>Violet, Dog-Tooth</COMMON> <BOTANICAL same-name="17 18"> <GENUS>Erythronium</GENUS> <SPECIES>americanum</SPECIES> </BOTANICAL> <ZONE>4</ZONE> <LIGHT>Shade</LIGHT> <PRICE unit="euro">9.04</PRICE> <AVAILABILITY>020199</AVAILABILITY> </PLANT> <PLANT id="17"> <COMMON>Trout Lily</COMMON> <BOTANICAL same-name="16 18"> <GENUS>Erythronium</GENUS> <SPECIES>americanum</SPECIES> </BOTANICAL> <ZONE>4</ZONE>
22
Variante avec identifiants (3/3)
Un nom d'attribut sans préfixe n'appartient à aucun espace de noms, même s'il y a un espace de noms par défaut
Pour reconnaître l'attribut, ne pas utiliser le préfixe d'espace de noms
<xsl:variable name="meme-nom" select="key('botanical-to-plant', .) [not(jr:BOTANICAL is current())]"/> <xsl:if test="$meme-nom"> <xsl:attribute name="same-name" select="$meme-nom/@id"/> </xsl:if>
<CATALOG xmlns="http://igm.univ-mlv.fr/~laporte/jardinerie"> <PLANT id="1"> <COMMON>Bloodroot</COMMON>
23
Index des horaires de métro (1/7)
ligne7.xml donne les horaires des premiers et derniers métros dans chaque station
Faire un index des horaires
0:25 : La Courneuve - 8 Mai 1945 ; 0:27 : Fort d'Aubervilliers ; La Courneuve - 8 Mai 1945 ; 0:29 : Aubervilliers - Pantin - Quatre Chemins ; Fort d'Aubervilliers ; 0:31 : Aubervilliers - Pantin - Quatre Chemins ; Porte de La Villette ; 0:32 : Corentin Cariou ;
24
Index des horaires de métro (2/7)
Indexer les <td headers="station"> par les horaires
<tbody> (...) <tr> <td class="h"> <span/> </td> <td class="carte"> <a href="http://www.ratp.info/Proxi/proxi.php" onclick="proxi('604933;2435111'); return false;"> <img src="..." alt="Plan de quartier"/> </a> </td> <td id="fort_d_aubervilliers" headers="station" class="gauche">Fort d'Aubervilliers</td> <td headers="pre_dep_sem fort_d_aubervilliers" class="espace"/> <td headers="pre_dep_sem fort_d_aubervilliers">5:30</td> <td headers="pre_dep_sem fort_d_aubervilliers">5:34</td>
25
Index des horaires de métro (3/7)
tbody
tr
tdtd
a Fort d'Aubervilliers
tr
...
td td
5:30
...
noeud à indexer
clés d'indexation
td
5:34
26
Index des horaires de métro (4/7)
Indexer les <td headers="station"> par les horaires
<xsl:strip-space elements="*"/> <xsl:key name="heure-station" match="xh:tbody/xh:tr/xh:td[@headers='station']" use="../xh:td[matches(.,'^[0-7]:[0-5][0-9]')]"/>
<tbody> (...) <tr> (...) <td id="fort_d_aubervilliers" headers="station" class="gauche">Fort d'Aubervilliers</td> <td headers="pre_dep_sem fort_d_aubervilliers" class="espace"/> <td headers="pre_dep_sem fort_d_aubervilliers">5:30</td> <td headers="pre_dep_sem fort_d_aubervilliers">5:34</td>
27
Index des horaires de métro (5/7)
Parcourir l'ensemble des heures
<xsl:template match="xh:table"> <xsl:for-each-group select="xh:tbody/xh:tr/xh:td[matches(.,'^[0-7]:[0-5][0-9]')]" group-by="."> <xsl:sort select="current-grouping-key()"/> <xsl:call-template name="horaire"> <xsl:with-param name="heure" select="current-grouping-key()"/> </xsl:call-template> </xsl:for-each-group> </xsl:template>
28
Index des horaires de métro (6/7)
Pour une clé, parcourir les noeuds indexés par cette clé
<xsl:template name="horaire"> <xsl:param name="heure" select="'not found'"/> <xsl:value-of select="$heure"/> <xsl:text> : </xsl:text> <xsl:for-each select="key('heure-station',$heure)"> <xsl:sort select="." lang="fr"/> <xsl:value-of select="."/> ; </xsl:for-each> <xsl:text></xsl:text> </xsl:template>
29
Index des horaires de métro (7/7)
<xsl:key name="heure-station" match="xh:tbody/xh:tr/xh:td[@headers='station']" use="../xh:td[matches(.,'^[0-7]:[0-5][0-9]')]"/>
tr
tdtd
a Fort d'Aubervilliers
td td
5:30
...
noeud à indexer
clés d'indexation
td
5:34
30
. ../*
..
*@
../../*
*/*
@*
31
preceding::* following::*
descendant::*
ancestor::*
self::*
following-sibling::*preceding-sibling::*
parent::*
child::*@attribute::*
32
Axes Xpath (1/6)
<xsl:key name="heure-station" match="xh:tbody/xh:tr/xh:td[@headers='station']" use="following-sibling::xh:td[matches(.,'^[0-7]:[0-5][0-9]')]"/>
tr
tdtd
a Fort d'Aubervilliers
td td
5:30
...
noeud à indexer
clés d'indexation
td
5:34
33
Axes (2/6)
*[.=':'] abréviation pour child::*[.=':']..[.=':'] parent::node()[.=':'].[.=':'] self::node()[.=':']@*[.=':'] attribute::*[.=':']node()[.=':'] child::node()[.=':']*/*[.=':'] child::*/child::*[.=':']../*[.=':'] parent::node()/child::*[.=':']../xh:td[.=':'] parent::node()/child::xh:td[.=':']../../*[.=':'] parent::node()/parent::node()/child::*[.=':']
34
Axes (3/6)
Certaines expressions n'ont aucune abréviation possibleparent::xh:tr[.=':']
../xh:tr[.=':'] parent::node()/child::xh:tr[.=':']parent::*[.=':']following-sibling::*[.=':']
Chaque étape peut avoir un ou plusieurs prédicats*[.=':']/* child::*[.=':']/child::**[.=':'][position()=1]/* child::*[.=':'][position()=1]/child::*
L'expression * ne sélectionne que des éléments, sauf dans @* et attribute::*
35
Axes (4/6)
Parenthésage interditchapitre/section|chapitre/figure OKchapitre/(section|/figure) interdittr[@class='blue']|td[@class='blue'] OK(tr|td)[@class='blue'] interditdescendant::*|self::* OK(descendant|self)::* interditdescendant-or-self::* OKancestor-or-self::* OK
36
Axes (5/6)
//*[.=':'] /descendant-or-self::node()/child::*[.=':']
//xh:td[.=':'] /descendant-or-self::node()/child::xh:td[.=':']
.//.[.=':']self::node()/descendant-or-self::node()/self::node()[.=':']
37
Axes (6/6)
Ordre d'une liste de noeudsSert à évaluer position()
Pour la plupart des axesOrdre du document[position()=1] sélectionne le premier noeud
Pour les axes qui "remontent" dans le document (ancestor - preceding-sibling - preceding - ancestor-or-self)De droite à gauche[position()=1] sélectionne le noeud le plus à droite ou le plus bas dans l'arbre
38
Extraction à partir d'un documentmal structuré (1/7)
ligne7.xml est structuré pour la visualisation uniquementExtraire les missions des premiers et derniers trains (liste des stations avec les heures de passage)
39
Extraction à partir d'un documentmal structuré (2/7)
ligne7.xml est structuré pour la visualisationOn va indexer les horaires par les noms des stations
<tr class="impair"> <td class="g"> <span/> </td> <td class="carte"> <a href="http://www.ratp.info/Proxi/proxi.php" onclick="proxi('601400;2425884'); return false;"> <img src="horaires_metro7.php_fichiers/picto_carte.gif" alt="Plan de quartier"/> </a> </td> <td id="place_d_italie" headers="station" class="gauche"> <strong>Place d'Italie</strong> </td> <td headers="pre_dep_sem place_d_italie" class="espace">6:00</td> <td headers="pre_dep_sem place_d_italie">6:06</td> <td headers="pre_dep_sem place_d_italie">6:10</td> <td headers="der_dep_sem place_d_italie" class="espace_2">1:03</td> <td headers="der_dep_sem place_d_italie">1:05</td>
40
Extraction à partir d'un documentmal structuré (3/7)
Indexer les horaires par les noms des stations
tr
tdtd
a Fort d'Aubervilliers
td td
5:30
...
noeud à indexer
clé d'indexation
td
5:34
41
Extraction à partir d'un documentmal structuré (4/7)
Indexer les horaires par les noms des stations
<xsl:strip-space elements="*"/> <xsl:key name="mission-1" match="xh:tbody/xh:tr/xh:td[position()=4]" use="preceding-sibling::xh:td[@headers='station']"/> <xsl:key name="mission-2" match="xh:tbody/xh:tr/xh:td[position()=5]" use="preceding-sibling::xh:td[@headers='station']"/>
42
Extraction à partir d'un documentmal structuré (5/7)
<xsl:template match="xh:table"> <missions> <mission> <!-- parcourir les noms des stations --> <xsl:apply-templates select="xh:tbody/xh:tr/xh:td[@headers='station']"> <xsl:with-param name="index-station-heure" select="'mission-1'"/> </xsl:apply-templates> </mission>(...) <xsl:template match="xh:td"> <xsl:param name="index-station-heure" select="'not found'"/> <xsl:variable name="heure" select="key($index-station-heure,.)"/> <xsl:if test="$heure/text()"> <!-- récupérer l'heure de l'arrêt --> <arret heure="{$heure}"> <xsl:value-of select="."/> </arret> </xsl:if> </xsl:template>
43
Extraction à partir d'un documentmal structuré (6/7)
<?xml version="1.0" encoding="ISO-8859-1"?><missions xmlns:xh="http://www.w3.org/1999/xhtml"> <mission> <arret heure="5:30">Corentin Cariou</arret> <arret heure="5:31">Crimée</arret> <arret heure="5:32">Riquet</arret> <arret heure="5:33">Stalingrad</arret> <arret heure="5:35">Louis Blanc</arret> <arret heure="5:36">Château-Landon</arret> <arret heure="5:37">Gare de l'Est</arret> <arret heure="5:39">Poissonnière</arret> <arret heure="5:40">Cadet</arret> <arret heure="5:42">Le Peletier</arret> <arret heure="5:43">Chaussée d'Antin - La Fayette</arret>
Résultat
44
Extraction à partir d'un documentmal structuré (7/7)
Un appel par noeud peut transmettre des paramètres
<mission> <xsl:apply-templates select="xh:tbody/xh:tr/xh:td[@headers='station']"> <xsl:with-param name="index-station-heure" select="'mission-1'"/> </xsl:apply-templates> </mission>(...) <xsl:template match="xh:td"> <xsl:param name="index-station-heure" select="'not found'"/> <xsl:variable name="heure" select="key($index-station-heure,.)"/>(...) </xsl:template>
45
Donner une structureà un document "aplati" (1/7)
Toutes les balises sont des éléments vides (sauf pour l'élément racine)
<?xml version="1.0" encoding="ISO-8859-1"?><CATALOG><PLANT/><COMMON/>Bloodroot<BOTANICAL/>Sanguinaria canadensis<ZONE/>4<LIGHT/>Mostly Shady<PRICE/>2.44<AVAILABILITY/>031599<PLANT/><COMMON/>Columbine<BOTANICAL/>Aquilegia canadensis
46
Donner une structureà un document "aplati" (2/7)
Structure du document "aplati"
PLANT
CATALOG
COM BOT ZONE PLANT
Bloodroot
Sanguinaria Canadensis
4
47
Donner une structureà un document "aplati" (3/7)
Structure souhaitée
PLANT
CATALOG
COM BOT ZONE
PLANT
Bloodroot
Sanguinaria Canadensis
4
48
Donner une structureà un document "aplati" (4/7)
Méthode : créer des relations "clé/noeud indexé" qui correspondent aux futures relations "élément père/élément fils"
PLANT
CATALOG
COM BOT ZONE PLANT
Bloodroot
Sanguinaria Canadensis
4
clé
noeudindexé
49
Donner une structureà un document "aplati" (5/7)
Les clés sont des chaînes de caractèresUtiliser les identifiants des noeuds
PLANT
CATALOG
COM BOT ZONE PLANT
Bloodroot
Sanguinaria Canadensis
4
clé
noeudindexé
50
Donner une structureà un document "aplati" (6/7)
<xsl:key name="parent-to-child" match="PLANT" use="generate-id(..)"/> <xsl:key name="parent-to-child" match="CATALOG/*[local-name()!='PLANT']" use="generate-id(preceding-sibling::PLANT[1])"/>(...) <xsl:template match="CATALOG"> <xsl:copy> <xsl:apply-templates select="key('parent-to-child', generate-id(.))"/> </xsl:copy> </xsl:template>
51
Donner une structureà un document "aplati" (7/7)
<xsl:template match="PLANT"> <xsl:copy> <xsl:apply-templates select="key('parent-to-child', generate-id(.))"/> </xsl:copy> </xsl:template> <xsl:template match="CATALOG/*[local-name()!='PLANT']"> <xsl:copy> <xsl:value-of select="normalize-space(following-sibling::text()[1])"/> </xsl:copy> </xsl:template>
52
Résultat
<?xml version="1.0" encoding="ISO-8859-1"?><CATALOG> <PLANT> <COMMON>Bloodroot</COMMON> <BOTANICAL>Sanguinaria canadensis</BOTANICAL> <ZONE>4</ZONE> <LIGHT>Mostly Shady</LIGHT> <PRICE>2.44</PRICE> <AVAILABILITY>031599</AVAILABILITY> </PLANT> <PLANT> <COMMON>Columbine</COMMON> <BOTANICAL>Aquilegia canadensis</BOTANICAL> <ZONE>3</ZONE> <LIGHT>Mostly Shady</LIGHT> <PRICE>9.37</PRICE>
53
Produire plusieurs documents (1/3)
Un index alphabétique des plantes en XHTML avec des liens vers une 2e page XHTML pour les entrées du catalogue
<xsl:template match="jr:CATALOG"> <xsl:result-document href="index.xhtml"> <html>(...) <body> <h1>Plant Index</h1> <div class="index"> <xsl:apply-templates select="jr:PLANT" mode="index"> <xsl:sort/> </xsl:apply-templates> </div> </body> </html> </xsl:result-document>
54
Produire plusieurs documents (2/3)
<xsl:result-document href="plant_catalog_jr.xhtml"> <html> <head> <link href="plant-CSS/plant.css" type="text/css" rel="stylesheet"/> <title>Plant Catalog</title> </head> <body> <h1>Plant Catalog</h1> <xsl:apply-templates select="jr:PLANT" mode="catalogue"/> </body> </html> </xsl:result-document> </xsl:template>
55
Produire plusieurs documents (3/3)
<xsl:template match="jr:PLANT" mode="index"> <a href="plant_catalog_jr.xhtml#{generate-id()}"> <xsl:value-of select="jr:COMMON"/> </a> <br/> </xsl:template> <xsl:template match="jr:PLANT" mode="catalogue"> <hr/> <br/> <table class="catalog"> <tr> <td class="cell"> <a name="{generate-id()}"/> <h2><xsl:value-of select="jr:COMMON"/></h2>
56
Résultat : l'index
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns:jr="http://igm.univ-mlv.fr/~laporte/jardinerie" xmlns="http://www.w3.org/1999/xhtml"> <head> <link href="plant-CSS/plant.css" type="text/css" rel="stylesheet"/> <title>Plant Index</title> </head> <body> <h1>Plant Index</h1> <div class="index"> <a href="plant_catalog_jr.xhtml#d1e276">Adder's-Tongue</a> <br/> <a href="plant_catalog_jr.xhtml#d1e292">Anemone</a>
57
Résultat : le catalogue
<body> <h1>Plant Catalog</h1> <hr/> <br/> <table class="catalog"> <tr> <td class="cell"> <a name="d1e3"/> <h2>Bloodroot</h2> <i>Sanguinaria canadensis</i> <p>4</p> <p>Mostly Shady</p> <p>031599</p> <b>2.44</b> </td>
58
Analyser du texte (1/2)
Combien de fois "murder" apparaît-il dans bergman.xml ?
<xsl:template match="/"> <xsl:variable name="occurrences"> <xsl:analyze-string select="." regex="[mM]urder"> <xsl:matching-substring> <one-occ/> </xsl:matching-substring> </xsl:analyze-string> </xsl:variable> <xsl:message> <xsl:value-of select="count($occurrences/one-occ)"/> occurrences </xsl:message> </xsl:template>
59
Analyser du texte (2/2)
analyze-string découpe le texte en tokens correspondant et ne correspondant pas au motif donné
On construit un arbre dans une constanteOn compte des noeuds dans l'arbre
<xsl:variable name="occurrences"> <xsl:analyze-string select="." regex="[mM]urder"> <xsl:matching-substring> <one-occ/> </xsl:matching-substring> </xsl:analyze-string> </xsl:variable> <xsl:message> <xsl:value-of select="count($occurrences/one-occ)"/> occurrences </xsl:message>
Recommended