I. variable xslt▲
I-A. Déclarations des variables▲
<?xml version="1.0" encoding="UTF-8"?>
<racine>
<valeur>
1</valeur>
<valeur>
2</valeur>
</racine>
Pour la suite des exemples de ce paragraphe, nous prendrons ce xml comme références. Le terme de « variable » peut être trompeur ; en effet la variable xslt
<
xsl
:
variable
name
=
""
/>
voit sa valeur fixée dès son initialisation, celle-ci se faisant soit par l'attribut select contenant un xpath, soit par des valeurs entre les balises. Etc.
<
xsl
:
variable
name
=
"var1"
select
=
"/A"
/>
<
xsl
:
variable
name
=
"var2 "
>
ceci</
xsl
:
variable>
<
xsl
:
variable
name
=
"var3"
><
xsl
:
value-of
select
=
" ."
/></
xsl
:
variable>
Une fois ces balises écrites, le contenu ne pourra plus être modifié et sera appelé par l'attribut name de la balise concernée, précédée du signe $
<
xsl
:
value-of
select
=
"$var2"
/>
Attention si on ne peut modifier sa valeur, rien n'interdit de créer une nouvelle variable de même nom dans un autre nœud. Voir la fin du paragraphe suivant.
I-B. Portée de la variable▲
La portée d'une variable xslt est intimement liée à la structure xml du xslt, en effet elle correspond exactement au nœud dans lequel elle est déclarée et à tous les descendants de ce nœud. Ici des exemples seront certainement plus parlant ainsi
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"html"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var1"
>
a</
xsl
:
variable>
<
xsl
:
template
match
=
"/"
>
<
xsl
:
variable
name
=
"var2"
>
b</
xsl
:
variable>
<html>
<body>
appel premier template
<br/>
<
xsl
:
value-of
select
=
"$var1"
/>
<br/>
<
xsl
:
value-of
select
=
"$var2"
/>
<br/>
<
xsl
:
apply-templates
select
=
"//valeur"
></
xsl
:
apply-templates>
</body>
</html>
</
xsl
:
template>
<
xsl
:
template
match
=
"valeur"
>
<
xsl
:
variable
name
=
"var3"
>
c</
xsl
:
variable>
appel deuxième template
<br/>
<
xsl
:
value-of
select
=
"$var1"
/>
<br/>
<
xsl
:
value-of
select
=
"$var2"
/>
<br/>
<
xsl
:
value-of
select
=
"$var3"
/>
<br/>
</
xsl
:
template>
</
xsl
:
stylesheet>
xsl:template match=« / » provoquera une erreur de du processeur xslt, sur la ligne soulignée. En effet, la variable var2 est déclarée dans la première template, mais comme la secondexsl:template match=« valeur » n'appartient pas à ses descendants elle y est inconnue. Par contre, après suppression de la ligne en erreur, on s'apercevra que var1 qui est déclarée dans la balise racinexsl:stylesheet version=« 1.0 » xmlns:xsl=« http://www.w3.org/1999/XSL/Transform » du document sera, elle, reconnue dans toute la feuille xslt.
<html>
<body>
appel première template
<br/>
a<br/>
b<br/>
appel deuxième template
<br/>
a<br/>
c<br/>
appel deuxième template
<b/r>
a<br/>
c<b/r>
</body>
</html>
Attention ce qui est dit ici pour les templates est vrai pour tous les nœuds.
<
xsl
:
if
test
=
"current()"
>
<
xsl
:
variable
name
=
"var4"
select
=
"."
/>
<
xsl
:
value-of
select
=
"$var4"
/>
</
xsl
:
if>
fonctionnera, alors que :
<
xsl
:
if
test
=
"current()"
>
<
xsl
:
variable
name
=
"var4"
select
=
"."
/>
</
xsl
:
if>
<
xsl
:
value-of
select
=
"$var4"
/>
produira une erreur ;var4 disparaissant à la sortie du nœud xsl:if test=« current() ».
Note : le code ci-dessous est tout à fait valable :
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"html"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var1"
select
=
"//valeur[2]"
></
xsl
:
variable>
<
xsl
:
template
match
=
"/"
>
<html>
<body>
<
xsl
:
variable
name
=
"var1"
select
=
"$var1+10"
></
xsl
:
variable>
<
xsl
:
value-of
select
=
"$var1"
/>
<br/>
<
xsl
:
apply-templates
select
=
"//valeur"
></
xsl
:
apply-templates>
</body>
</html>
</
xsl
:
template>
<
xsl
:
template
match
=
"valeur"
>
<
xsl
:
value-of
select
=
"$var1"
/>
<br/>
</
xsl
:
template>
</
xsl
:
stylesheet>
En effet, on crée ici une variable locale au nœud xsl:template match=« / », qui prend le pas sur la précédente. Ce sont donc deux variables différentes, et non pas la modification de la première. D'ailleurs le résultat est :
<html>
<body>
12<br/>
2<br/>
2<br/></body>
</html>
La valeur de la variable n'a pas été modifiée, une variable « locale » a simplement pris temporairement le pas sur la « globale ».
I-C. Contenue d'une variable▲
une variable peut contenir ces différents types de données: string, number, boolean, node-set qui appartiennent tous à Xpath ,plus le type node-fragment qui lui est particulier.
<
xsl
:
variable
name
=
"var1"
select
=
"number(10.2)"
/>
<
xsl
:
variable
name
=
"var2"
>
15.2</
xsl
:
variable>
<
xsl
:
variable
name
=
"var3"
>
truc</
xsl
:
variable>
<
xsl
:
variable
name
=
"var4"
select
=
"string('truc')"
/>
<
xsl
:
variable
name
=
"var5"
select
=
"$var1 < $var2"
/>
Une autre façon de déclarer des string ou des number que vous pouvez avoir vu
<
xsl
:
variable
name
=
"var2"
>
15.2</
xsl
:
variable>
<
xsl
:
variable
name
=
"var3"
>
truc</
xsl
:
variable>
attention ce type d'écriture s’il est sans conséquence pour l'affichage peut entraîner des erreurs de tests. Ceci sera plus détaillé à la fin des node-fragment
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"html"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var1"
select
=
"number(10.2)"
/>
<
xsl
:
variable
name
=
"var2"
>
15.2</
xsl
:
variable>
<
xsl
:
variable
name
=
"var3"
>
truc</
xsl
:
variable>
<
xsl
:
variable
name
=
"var4"
select
=
"string('truc')"
/>
<
xsl
:
variable
name
=
"var5"
select
=
"$var1 < $var2"
/>
<
xsl
:
template
match
=
"/"
>
<html>
<body>
<
xsl
:
value-of
select
=
"$var1"
/>
<br/>
<
xsl
:
value-of
select
=
"$var2"
/>
<br/>
<
xsl
:
value-of
select
=
"$var3"
/>
<br/>
<
xsl
:
value-of
select
=
"$var4"
/>
<br/>
<
xsl
:
value-of
select
=
"$var5"
/>
<br/>
</body>
</html>
</
xsl
:
template>
</
xsl
:
stylesheet>
<html>
<body>
10.2<br>
15.2<br>
truc<br>
truc<br>
true<br></body>
</html>
Pour les types node-set, il faut noter qu'un de leurs grands avantages est de pouvoir être utilisés dans des expressions xpath par exemple :
<
xsl
:
variable
name
=
"var1"
select
=
"/racine"
/>
<
xsl
:
variable
name
=
"var2"
select
=
"//valeur"
/>
$var2[1] permettra d'accéder à la première balise valeur, mais $var1/valeur[1] aussi. Toutes les expressions xpath sont utilisables sur une variable et une variable peut être aussi utilisée dans une expression.
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"html"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var1"
select
=
"/racine"
/>
<
xsl
:
variable
name
=
"var2"
select
=
"//valeur"
/>
<
xsl
:
template
match
=
"/"
>
<html>
<body>
<
xsl
:
value-of
select
=
"$var2[1]"
/>
<br></br>
<
xsl
:
value-of
select
=
"$var1/valeur[1]"
/>
<br></br>
<
xsl
:
if
test
=
"$var1/valeur[1]=$var2[1]"
>
les deux expressions ont la même valeur.
</
xsl
:
if>
</body>
</html>
</
xsl
:
template>
</
xsl
:
stylesheet>
<html>
<body>
1<br>
1<br>
les deux expressions ont la même valeur.
</body>
</html>
Enfin le dernier type qui est propre a la variable le node fragment. Le but est de (re-)créer des nœuds xml dans la variable et non le xpath (surtout si ceux-ci n'existent pas) exemple :
<
xsl
:
variable
name
=
"var"
>
<truc>
premier truc
</truc>
<truc>
second truc
</truc>
</
xsl
:
variable>
attention, aucun xpath ne peut être utilise sur un node fragment, les [] et / sont interdits, et seuls les opérateurs sur les chaînes de caractères sont autorisés (length(),substring…). Un value of select de ce type de variable ne rendra comme résultat que le contenu des balises, pas les balises elles-mêmes :
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"html"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var"
>
<racine>
<truc>
premier truc
</truc>
<truc>
second truc
</truc>
</racine>
</
xsl
:
variable>
<
xsl
:
template
match
=
"/"
>
<html>
<body>
<
xsl
:
value-of
select
=
"$var"
/>
</body>
</html>
</
xsl
:
template>
</
xsl
:
stylesheet>
<html>
<body>
premier truc
second truc
</body>
</html>
L'intérêt de ce type de variable se trouve plutôt dans la construction d'arbre xml, chapitre que nous verrons ultérieurement. Notons simplement que le xsl:copy-of prend lui en compte la présence des balises :
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"xml"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var"
>
<racine>
<truc>
premier truc
</truc>
<truc>
second truc
</truc>
</racine>
</
xsl
:
variable>
<
xsl
:
template
match
=
"/"
>
<
xsl
:
copy-of
select
=
"$var"
>
</
xsl
:
copy-of>
</
xsl
:
template>
</
xsl
:
stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<racine>
<truc>
premier truc
</truc>
<truc>
second truc
</truc>
</racine>
Note : attention de ne pas abuser de ce type d'écriture si l'on ne veut pas créer un node fragment. En effet cela peut perturber le processeur dans des tests,comme suit :
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"xml"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var"
>
2
</
xsl
:
variable>
<
xsl
:
template
match
=
"/"
>
<html>
<body>
<
xsl
:
value-of
select
=
"racine/valeur[$var]"
>
</body>
</html
</
xsl
:
template>
</
xsl
:
stylesheet>
<html>
<body>
1
</body>
</html
En effet, ici $var n'est pas interprété comme un nombre.Si vous désirez gardez cette écriture de variable alors il vous faudra :
<
xsl
:
value-of
select
=
"racine/valeur[position()=$var]"
>
ou
<
xsl
:
value-of
select
=
"racine/valeur[number($var)]"
>
Pour finir, il est tout à fait possible, de faire appel par des apply-templates ou des call-templates (détail ultérieurement) à l'intérieur d'une variable. Le seul type de résultat inaccessible dans ce cas étant le node-set.
<?xml version="1.0" encoding="UTF-8"?>
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl
:
output
method
=
"html"
version
=
"1.0"
encoding
=
"UTF-8"
indent
=
"yes"
/>
<
xsl
:
variable
name
=
"var"
>
<
xsl
:
apply-templates
select
=
"//valeur"
/>
</
xsl
:
variable>
<
xsl
:
template
match
=
"/"
>
<html>
<body>
<
xsl
:
value-of
select
=
"$var"
/>
</body>
</html>
</
xsl
:
template>
<
xsl
:
template
match
=
"valeur"
>
<
xsl
:
value-of
select
=
"concat(.,';')"
/>
</
xsl
:
template>
</
xsl
:
stylesheet
<html>
<body>
1;2;</body>
</html>