1. variable xslt

1.1. Déclarations des variables

fichier xml de référence
Sélectionnez
<?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

 
Sélectionnez
<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....

exemples
Sélectionnez
<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 $

exemple
Sélectionnez
<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 noeud. Voir la fin du paragraphe suivant.

1.2. 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 noeud dans lequel elle est déclarée et à tous les descendants de ce noeud. Ici des exemples seront certainement plus parlant ainsi

 
Sélectionnez
<?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 a 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 feuilles xslt.

Le résultat:
Sélectionnez
<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 noeuds.

Exemple:
Sélectionnez
<xsl:if test="current()">
	<xsl:variable name="var4" select="."/>
	<xsl:value-of select="$var4"/>
</xsl:if>

fonctionnera, alors que:

 
Sélectionnez
<xsl:if test="current()">
	<xsl:variable name="var4" select="."/>
</xsl:if>
<xsl:value-of select="$var4"/>

produira une erreur ;var4 disparaissant à la sortie du noeud xsl:if test="current()". Note: le code ci-dessous est tout à fait valable:

 
Sélectionnez
<?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 noeud 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:

 
Sélectionnez
<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" .

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

number
Sélectionnez
<xsl:variable name="var1" select="number(10.2)"/>
	<xsl:variable name="var2" >15.2</xsl:variable>
string
Sélectionnez
<xsl:variable name="var3" >truc</xsl:variable>
	<xsl:variable name="var4"  select="string('truc')"/>
booleen
Sélectionnez
<xsl:variable name="var5" select="$var1 < $var2"/>

une autre façon de déclarer des string ou des number que vous pouvez avoir vu

 
Sélectionnez
<xsl:variable name="var2" >15.2</xsl:variable>
<xsl:variable name="var3" >truc</xsl:variable>

attention ce type d'écriture si 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

fichier xslt
Sélectionnez
<?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>
résultat
Sélectionnez
<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 leur grand avantage est de pouvoir être utilisée dans des expressions xpath par exemple:

 
Sélectionnez
<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 utiliser dans une expression.

fichier xslt
Sélectionnez
<?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>
résultat
Sélectionnez
<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 noeuds xml dans la variable et non le xpath(surtout si ceux ci n'existent pas) exemple:

 
Sélectionnez
<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 seul 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

fichier xslt
Sélectionnez
<?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>
résultat
Sélectionnez
<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

fichier xslt
Sélectionnez
<?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>
résultat
Sélectionnez
<?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:

fichier xslt
Sélectionnez
<?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>
résultat
Sélectionnez
<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:

 
Sélectionnez
<xsl:value-of select="racine/valeur[position()=$var]">

ou

 
Sélectionnez
<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.

fichier xslt
Sélectionnez
<?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
résultat
Sélectionnez
<html>
 
<body>1;2;</body>
 
</html>