Bonsoir les gens,

Je passe juste partager une « astuce » pratique que je n'ai appliqué que tout récemment, bien qu'elle existe depuis déjà un certain temps. Je ne l'avais jamais appliqué, parce que j'essaie toujours de faire les choses avec ce que j'ai sous la main (souvent le plus rudimentaire), sans trop de gadgets.

XSLT répond à la plupart des besoins, mais il lui manque logiquement quelque chose : la possibilité d'utiliser des variables en lieu et place des chemins XPath.

Si cette caractéristique n'est pas présente dans le standard, c'est probablement seulement pour des raisons d'efficacité, .... pour des raisons techniques donc, et non pas pour des raisons logiques. Le concept d'utiliser des variables de chemin, n'introduit en effet aucune incohérence dans le principe de XSLT ni dans celui de XPath.

Le principe peut être résumé comme suit, en guise de court exemple également :

Un ensemble de noeuds dans une variable, soit $NodeSet
Une variables texte dont le texte représente un chemin XPath syntaxiquement valide, soit $XPath

Il est possible en XSLT, d'avoir alors quelque chose comme

<xsl:apply-templates select="$NodeSet/element1/element2" />


Mais même si la variable texte $XPath est assignée à "element1/element2", il ne sera pas possible d'utiliser une expression comme (elle renverra une erreur de compilation de la feuille, bien que sa formulation semble logique)

<xsl:apply-templates select="$NodeSet/$XPath" />


Ceci, comme je le disais, probablement plus pour des raison d'efficacité que pour des raisons logique : les processeurs XSLT attendent des chemins déterminés statiquement à la compilation de la feuille de transformation.

Pourtant l'utilisation de variables de chemin peut parfois représenter la solution la plus évidente et la plus propre à un problème.

Que faire alors ?

La solution est donnée par EXSLT, qui comme son nom l'indique est une extension de XSLT.

Limitation : le processeur XSLT utilisé doit supporté l'extension adéquate.

Comment l'utiliser : si votre processeur XSLT le supporte, il faut ajouter dans la balise « transform », l'espace de nom correspondant :

<xsl:transform
	version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:dyn="http://exslt.org/dynamic"
	extension-element-prefixes="dyn">



L'attribut « xmlns:dyn » introduit l'espace de nom, et l'attribut extension-element-prefixes (qui est en fait une liste), introduit un préfixe pour les fonctions (la notation à l'usage est la même que pour les préfixes d'espaces de noms)

L'ajout de ces deux attributs à l'élément racine « transform », introduit le module http://exslt.org/dynamic qui contient la fonction « evaluate », qui va nous permettre d'utiliser des variables de chemin XPath

Notre précédente variable, pourra alors être utilisée comme suit :

<xsl:apply-templates select="dyn:evaluate(concat('$NodeSet/', $XPath))" />


Deux choses sont à noter ici :
1) l'utilisation du prefixe « dyn: » pour utiliser la fonction « evaluate », « evaluate » n'étant pas une fonction standard de XPath, comme nous l'avons vu
2) l'utilisation de la fonction standard « concat », renvoyant une chaîne, pour créer l'argument de « evaluate »

Concernant le deuxième point : en effet, la fonction « evaluate » attend une chaîne en argument, et elle n'interpréterait pas directement une expression comme « $NodeNet/$XPath », raison pour laquelle, une chaîne est d'abord faite de la première partie du chemin, en la plaçant entre guillemets simples (les guillemets de l'attribut étant des guillemets doubles), puis à cette chaîne, est concaténée la valeur de la variable $XPath, qui elle, contrairement à la variable $NodeSet, est une variable chaîne. Remarque : attention à ne pas mettre $XPath entre guillemets donc, car nous simulons ici un chemin statique, en le faisant évaluer dynamiquement, et le problème que l'on résoud, est celui qui est que $XPath n'est pas un chemin statique ; mais le terme $XPath, ne fait pas parti du chemin, ... seulement son contenu !

Je vous laisse imaginer les applications pouvant êtres faites de variables de chemin, applications qui peuvent aller assez loin.

Testé avec XSLTProc, une ancienne version de plus, je n'en ai jamais changé, donc la solution est à priori assez abordable, à condition de ne pas espérer soumettre des feuilles de transformation à des navigateurs (ce qui est de toute manière toujours une mauvaise idée à mon avis), et de plutôt préférer appliquer les transformations au préalable.

Amusez-vous bien les lecteurs Smiley biggrin
Modifié par hibou57 (29 Sep 2009 - 22:26)
Bonjour,

En ajoutant des accolades, cela devrait fonctionner

<xsl:apply-templates select="{$NodeSet}/{$XPath}" />

David