XPATH est une syntaxe (et non pas un langage) pour localiser une portion d'un document XML.
Les exemples font souvent référence aux fichiers XML utilisés
pour enregistrer ces pages, on trouvera une description dans la
"Documentation technique du site" [http://www.dg77.net/tekno/sitedoc.htm#xml].
Expressions XPATH dans feuilles XSLT
Nom de l’élément parent
Soit un élément title dans un fichier Docbook.
S’il est sous une "sect1" (section de niveau 1), on veut mettre un titre de
niveau "h3" ; pour "sect2" on veut "h4", etc.
Eléments précédents et suivants
Enchaînement conditionnel de page. Condition : l’attribut e
doit être non vide (cf "Documentation technique du site" [http://www.dg77.net/tekno/sitedoc.htm#xml]).
On met des liens vers la page précédente et/ou
suivante si ces/cette page sont/est dans le même cas. Le noeud en cours
est un élément page, on vérifie l’attribut "e" de l’élément
page précédent ou suivant.
Amélioration du 16 dec 2004 : dans les attributs "title" et
"alt", on intègre les titres des pages concernées qui sont dans
l’élément /description/titre (variable $xtitre).
Données d’un autre élément
Suivant le même principe que précédemment, on utilise
le titre d’une page dont le nom du fichier est indiqué dans un
attribut "retour".
Exemples divers de traitements XSLT
Sélection d’un élément défini par variable.
Un élément au début du fichier XML en entrée :
Le “ template ” déclenché par la présence de d:somm :
On obtient ainsi la liste de tous les titres contenus dans des balises “h3”.
Test d’existence d’un élément et choix, traitement for each
sur une suite d’éléments.
Si l’élément où on se trouve ne contient pas d’élément fils
auteur, on va rechercher un autre élément auteur chez le "parent"
(i.e. au niveau supérieur, voir ci-dessous la recherche avec select="../auteur").
Voir l’exemple de la "galerie d’images" dans la page de
documentation du site..
Génération d’un fichier TXT — URLLIST d’un site
But
Création d’un fichier urllist.txt pour l’indexation par
l’annuaire/moteur de recherche Yahoo. Ce fichier contient simplement
la liste des URL des pages qu’on veut faire indexer. Les URL sont trouvés
dans les fichiers sources XML du site.
Source des données
Pour chaque page web au format XHTML, les balises se trouvent au
sein d’une balise page.
La structure des fichiers XML est la suivante (pour plus d’information
cf la page documentation du site [http://www.dg77.net/tekno/sitedoc.htm]) :
Transformation XSLT
La tâche consiste à récupérer le contenu de l’attribut
nomfic de la balise page et de le sortir dans le fichier urllist.txt.
Batch de lancement
Exemple, le fichier XSLT ci-dessus est nommé gen_urllist.xsl) :
Version améliorée
Dans la partie description, il est possible de spécifier une balise
meta. Le traîtement ci-dessous génère la ligne seulement
si la page n’a pas une balise meta du type name="robots" content="noindex".
Dans cette version, le nom du fichier et son chemin d’accès son passés
en paramètres aux templates suivants.
Génération de pages de redirection
Le site déménage. Comme dans l’exemple précédent,
on utilise les information de la balise page. Cette fois ci on crée
un fichier (x)html pour chaque page. Le nom de l’emplacement de sortie est passé
en paramètres.
Traîtement de chaînes de caractères
Chaînes de caractères : sous-chaînes et concaténation
Cet exemple crée un fichier WAP (.wml) à partir de chaque item
d’un fichier RSS 2.0.
Soit un fichier de news où chaque info est identifiée par
un nom dans l’élément guid, sous la forme XXXXX-9999,
"9999" étant un numérotage séquentiel (0000, 0001, 0002, etc.).
Chaque "item" doit générer un fichier Wap. Le but est de donner un nom
unique à chacun d’entre eux. On utilise le numéro inclu dans
<guid>. substring-after permet de récupérer le nombre
qui se trouve après (after) le caractère " - "
Avec "concat", on constitue le nom du fichier à sortir :
"F" suivi du numéro puis de l’extension ".wml".
Génération des liens entre item : chaque page wap a un lien vers la
précédente et la suivante (si elles existent), ainsi que vers la première et la dernière.
Le noeud en cours est un élément item,
on va ainsi lire l’élément guid de l’item précédent ou suivant. Noter qu’on utilise les
caractères "<" et ">" pour afficher les liens, ce qui entraîne l’utilisation de l’attribut
disable-output-escaping="yes" dans l’élément xsl:text.
Il convient d’utiliser l’entité représentant l’esperluette (&) pour que
les entités < et > (codes hexadecimaux équivalents à
< et >) soient vraiment reproduites dans le fichier en sortie.
 , équivalent de , insère une espace.
Les données du fichier XML supra donneront un fichier WML (WAP comme suit :
Affichage :
Remplacement conversion suppression de caractères
(translate replace)
La fonction replace change la suite de caractères
recherchée par celle qui est indiquée en remplacement :
replace($ma_chaine, 'quelque soit', 'quel que soit')
La fonction translate opère caractère par caractère. Exemple
pour supprimer les caractères accentués et autres :
translate($ma_chaine, 'éèçàùäëïöüâêîôû', 'eecauaeiouaeiou')
Pour remplacer œ par oe, il faudra utiliser replace
Les deux opérations font la même chose si on les utilise pour traîter un unique caractère.
Suppression dans une chaîne de caractères des éventuels espaces au début et
à la fin (les espaces internes sont préservés) :
Template XSLT récursif : génération du chemin de retour à la racine
Tous les liens internes du site utilisent des chemins relatifs. Par exemple
../design/dg77.css
signifie qu’on remonte d’un niveau de répertoire (remontée à la racine),
puis qu’on redescend dans le répertoire "design" pour y lire
le fichier css (feuille de style). Le chemin de retour
est conservé dans la variable $vch. Il est calculé par un "template" ad-hoc,
qui utilise les propriétés de récursivité d’XSLT. Le procédé
consiste, pour chaque nom de répertoire (chaîne de caractères
suivie par un "/") à ajouter "../" dans $vch.
Source d’inspiration : voir le tutorial d’IBM/Chuck White
"Analyze non-XML data with XSLT" [http://www-106.ibm.com/developerworks/edu/x-dw-xdataxslt-i.html]
sur l’utilisation de XSLT et sa récursivité.
Autres formules XSLT avancées
document : utilisation d’un fichier externe
Exemple pour le "log" général du site, enregistré sous le format standard RSS2.0
Ci-dessous, extrait simplifié du fichier log.xml. Noter l’utilisation d’un namespace (cf
la mention xmlns:dg) pour identifier des informations "maison" sans risque d’interférer
avec la définition officielle de RSS2 (namespace désigné par la
mention xmlns tout-court). Elles permettra en l’espèce de connaître
les dates de création et dernière modification du fichier au sein de la balise
<dg:description>.
Utilisation de l’instruction XSLT "document". Les pages utilisant un fichier externe
ont un lien pointant vers lui. Noter le test pour déterminer le type de fichier
ce qui permet de choisir l’icone et le type mime à spécifier.
Quand un fichier externe est utilisé, il est logique d’utiliser les dates indiquées
dans ce dernier, plutôt que celles du fichier xml appelant.
xsl:key (1) : regroupement -avec tri- (Grouping) d’éléments en fonction d’un attribut
Utilisation de la méthode "münchienne" [http://www.jenitennison.com/xslt/grouping/muenchian.html] .
Inspiré par David Carlyle
Soit le fichier répertoire téléphonique, où
chaque entrée a un attribut "rubr". Par exemple : f=famille,
w=travail, etc.
On veut lister ces éléments regroupés par code
@rubr" et triés sur @id.
Solution :
xsl:key (2) : récupérer un
texte en fonction d’un code
Pour chaque code "rubr" de l’exemple ci-dessus, une liste des libellés
correspondants figure en fin de fichier.
En tête de chaque groupe, on met un titre avec le libellé.
Remarque : dans cet exemple, on a utilisé le même nom
d’attribut (rubr) dans le fichier de données et dans la table mais
il peut très bien en aller autrement.
Si le chemin commence par '/', alors il représente un chemin absolu vers l’élément requis.
/AAA
Sélectionne l’élément racine AAA
/AAA/CCC
Sélectionne tous les éléments CCC qui sont enfants de l’élément racine AAA
/AAA/DDD/BBB
Sélectionne tous les éléments BBB qui sont enfants de DDD, qui sont enfants de l’élément racine AAA
Si le chemin commence par '//', alors tous les éléments du document qui correspondent au critère qui suit sont sélectionnés.
//BBB
Sélectionne tous les éléments BBB
//DDD/BBB
Sélectionne tous les éléments BBB qui sont enfants de DDD
L’étoile * sélectionne tous les éléments localisés par ce qui la précède dans le chemin
/AAA/CCC/DDD/*
Sélectionne tous les éléments inclus dans les éléments /AAA/CCC/DDD
/*/*/*/BBB
Sélectionne tous les éléments BBB qui ont trois ancêtres
//*
Sélectionne tous les éléments
Une expression entre crochets peut spécifier plus précisément un élément. Un nombre entre crochets donne la position d’un élément dans le jeu sélectionné. La fonction last sélectionne le dernier élément du jeu
/AAA/BBB[1]
Sélectionne le premier élément BBB, fils de l’élément racine AAA
/AAA/BBB[last()]
Sélectionne le dernier élément BBB, fils de l’élément racine AAA
Les attributs sont spécifiés par le préfixe @.
//@id
Sélectionne tous les attributs id
//BBB[@id]
Sélectionne tous les éléments BBB qui ont un attribut id
//BBB[@name]
Sélectionne tous les éléments BBB qui ont un attribut name
//BBB[@*]
Sélectionne tous les éléments BBB qui ont un attribut
//BBB[not(@*)]
Sélectionne tous les éléments BBB qui n’ont pas d’attribut
Les valeurs d’attributs peuvent être utilisées comme critère de sélection. La fonction normalize-space supprime les espaces de début et de fin puis remplace les séquences d’espaces blancs par un seul espace.
//BBB[@id='b1']
Sélectionne tous les éléments BBB ayant un attribut id dont la valeur est b1
//BBB[@name='bbb']
Sélectionne tous les éléments BBB ayant un attribut name dont la valeur est bbb
//BBB[normalize-space(@name)='bbb']
Sélectionne tous les éléments BBB ayant un attribut name dont la valeur est bbb. Les espaces de début et de fin sont supprimés avant la comparaison
La fonction count() compte le nombre d’éléments sélectionnés.
//*[count(BBB)=2]
Sélectionne les éléments ayant deux enfants BBB
//*[count(*)=2]
Sélectionne les éléments ayant deux enfants
//*[count(*)=3]
Sélectionne les éléments ayant trois enfants
La fonction name() retourne le nom de l’élément, la fonction start-with retourne vrai si la chaîne du premier argument commence par celle du deuxième et la fonction contains retourne vrai si la chaîne du premier argument contient celle du deuxième
//*[name()='BBB']
Sélectionne tous les éléments qui ont le nom BBB, équivalent à //BBB
//*[starts-with(name(),'B')]
Sélectionne tous les éléments dont le nom commence par la lettre B
//*[contains(name(),'C')]
Sélectionne tous les éléments dont le nom contient la lettre C
La fonction string-length retourne le nombre de caractères dans une chaîne. Vous devez utiliser < comme substitutif de < et > comme substitutif de >
//*[string-length(name()) = 3]
Sélectionne tous les éléments qui ont un nom dont le nombre de caractères est exactement trois
//*[string-length(name()) < 3]
Sélectionne tous les éléments qui ont un nom de un ou deux caractères
//*[string-length(name()) > 3]
Sélectionne tous les éléments qui ont un nom dont le nombre de caractères est strictement supérieur à trois
Plusieurs chemins peuvent être combinés avec le séparateur |
//CCC | //BBB
Sélectionne tous les éléments CCC et BBB
/AAA/EEE | //BBB
Sélectionne tous les éléments BBB et EEE qui sont enfants de l’élément racine AAA
/AAA/EEE | //DDD/CCC | /AAA | //BBB
Le nombre de combinaisons n’est pas restreint
L’axe enfant contient les enfants du noeud contextuel. L’axe enfant est celui par défaut et il peut être omis
/AAA
Equivalent à /child::AAA
/child::AAA
Equivalent à /AAA
/AAA/BBB
Equivalent à /child::AAA/child::BBB
/child::AAA/child::BBB
Equivalent à /AAA/BBB
/child::AAA/BBB
Les deux possiblilités peuvent être combinées
L’axe descendant (descendant) contient les descendants du noeud contextuel ; un descendant est un enfant ou un petit enfant etc. Aussi, l’axe descendant ne contient jamais de noeud de type attribut ou des noms d’espace.
/descendant::*
Sélectionne tous les descendants de l’élément racine et donc tous les éléments
/AAA/BBB/descendant::*
Sélectionne tous les descendants de /AAA/BBB
//CCC/descendant::*
Sélectionne tous les éléments qui ont CCC comme ancêtre
//CCC/descendant::DDD
Sélectionne les éléments DDD qui ont CCC comme ancêtre
L’axe "parent" contient le parent du noeud contextuel s’il en a un
//DDD/parent::*
Sélectionne tous les parents de l’élément DDD
L’axe ancêtre (ancestor) contient les ancêtres du noeud contextuel ; cela comprend son parent et les parents des parents etc. Aussi, cet axe contient toujours le noeud racine, sauf si le noeud contextuel est lui-même la racine.
/AAA/BBB/DDD/CCC/EEE/ancestor::*
Sélectionne tous les éléments donnés dans ce chemin absolu
//FFF/ancestor::*
Sélectionne tous les ancêtres de l’élément FFF
L’axe 'following-sibling' contient tous les noeuds frères qui suivent le noeud contextuel.
/AAA/BBB/following-sibling::*
Sélectionne tous les noeuds frères suivants de /AAA/BBB
//CCC/following-sibling::*
Sélectionne tous les noeuds frères suivants de l’élément CCC
L’axe 'preceding-sibling' contient tous les frères prédécesseurs du noeud contextuel ; si le noeud contextuel est un attribut ou un espace de noms, la cible précédente est vide.
/AAA/XXX/preceding-sibling::*
Sélectionne tous les noeuds frères prédécésseurs de /AAA/XXX
//CCC/preceding-sibling::*
Sélectionne tous les noeuds frères prédécésseurs de l’élément CCC
L’axe suivant (following) contient tous les noeuds du même document que le noeud contextuel qui sont après le noeud contextuel dans l’ordre du document, à l’exclusion de tout descendant, des attributs et des espaces de noms.
/AAA/XXX/following::*
Sélectionne tous les noeuds qui suivent /AAA/XXX dans le document et qui ne sont pas des descendants de cet élément
//ZZZ/following::*
Sélectionne tous les noeuds qui suivent l’élément ZZZ dans le document et qui ne sont pas des descendants de cet élément
L’axe cible précédente (preceding) contient tous les prédécesseurs du noeud contextuel ; si le noeud contextuel est un attribut ou un espace de noms, la cible précédente est vide.
/AAA/XXX/preceding::*
Sélectionne tous les noeuds qui précèdent le noeud /AAA/XXX dans le document qui ne sont pas ses parents
//GGG/preceding::*
Sélectionne tous les noeuds qui précèdent les éléments GGG dans le document qui ne sont pas ses parents
L’axe "descendant-or-self" contient le noeud contextuel et ses descendants
/AAA/XXX/descendant-or-self::*
Sélectionne le noeud /AAA/XXX et tous ses descendants
//CCC/descendant-or-self::*
Sélectionne tous les éléments CCC et leurs descendants
L’axe ancestor-or-self contient le noeud contextuel et ses ancêtres ; ainsi l’axe ancestor-or-self contient toujours le noeud racine
/AAA/XXX/DDD/EEE/ancestor-or-self::*
Sélectionne le noeud /AAA/XXX/DDD/EEE et tous ses ancêtres
//GGG/ancestor-or-self::*
Sélectionne tous les éléments GGG et tous leurs ancêtres
Les axes ancestor, descendant, following, preceding et self partitionnent un document (ignorant les attributs et les noeuds d’espace de nom) : il ne se chevauchent pas et ensemble ils contiennent tous les noeuds d’un document
//GGG/ancestor::*
Sélectionne tous les ancêtres des éléments GGG
//GGG/descendant::*
Sélectionne tous les descendants des éléments GGG
//GGG/following::*
Sélectionne tous les noeuds qui suivent les éléments GGG et qui ne sont pas des descendants de GGG
//GGG/preceding::*
Sélectionne tous les noeuds qui précèdent les éléments GGG et qui ne sont pas des ancêtres de GGG
L’opérateur div réalise une division à virgule flottante, l’opérateur mod retourne le reste d’une division. La fonction floor() retourne le plus grand nombre (le plus près de l’infini positif) qui n’est pas plus grand que l’argument et qui est un entier. La fonction ceiling() retourne le plus petit nombre (le plus près de l’infini négatif) qui n’est pas plus petit que l’argument et qui est un entier
//BBB[position() mod 2 = 0 ]
Sélectionne tous les éléments BBB dont la position dans l’arbre est un multiple de 2
//BBB[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]
Sélectionne le ou les éléments BBB qui se trouvent au milieu de tous les éléments BBB