1 <?xml version="1.0" encoding="utf-8" ?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
5 <html xmlns="http://www.w3.org/1999/xhtml" >
7 <title>XSLT (suite)</title>
9 <meta http-equiv="Content-Type"
10 content="text/html; charset=utf-8" />
11 <meta name="copyright"
12 content="Copyright © 2013 Kim Nguyễn" />
15 <script src="../jquery-1.9.1.min.js" type="text/javascript" ></script>
16 <!-- Load the library -->
17 <script src="../simpleWebSlides.js" type="text/javascript" ></script>
19 <link rel="stylesheet" href="../simpleWebSlides.css" type="text/css" media="all" />
20 <!-- Load a custom Theme, the class-element marks this style-sheet
21 a "theme" that can be swtiched dynamicaly -->
22 <link class="sws-theme" rel="stylesheet" title="U-Psud style" href="../themes/uPsud.css" type="text/css" />
24 <!-- Customize some templates and initialize -->
25 <style type="text/css">
26 .xml-tag { color: #00486c; }
28 <script type="text/javascript">
30 SWS.Config['sws-slide-change'] = SWS.Effects.slideChangeFadeOutIn;
31 SWS.Config['sws-object-deactivate'] = SWS.Effects.objectDeactivateFadeOut;
32 SWS.Config['sws-object-activate'] = SWS.Effects.objectActivateFadeIn;
34 //Ensures that we load SWS at the very end, after MathJax has
37 $(window).load(function () {
38 $(".inline-xml").each(function(i, elem)
41 var code = jelem.html();
42 code = code.replace ("<![CDATA" + "[", "").replace ("]" + "]>", "");
43 code = code.replace (/>/g, ">>>");
44 code = code.replace (/</g, "<span class='xml-tag'><");
45 code = code.replace (/>>>/g,"></span>");
51 var checkSVG = function (o, i)
53 if (i >= 10 || SWS.Utils.isUndefined(o) || o == null) return;
54 var svg = o.getSVGDocument();
56 setTimeout(function() { checkSVG(o, i+1); }, 200);
58 var alltext = $(svg).find("text");
59 alltext.css("font-family", "DIN");
60 alltext.css("font-size", "70%");
64 $(window).load(function() {
65 $("embed").ready(function() {
66 setTimeout(function() {
67 $("embed").each(function(i, o) { checkSVG(this,0); });
71 $(window).load(SWS.Presentation.init);
79 <a href="xpi_04.xhtml" class="sws-previous"/>
80 <div class="sws-slide sws-cover sws-option-nofooter">
81 <h1>XML et Programmation Internet</h1>
83 <a href="mailto:kn@lri.fr">kn@lri.fr</a>
85 <h1>Structures de contrôle</h1>
86 <div class="sws-slide">
87 <h1><tt>xsl:value-of</tt> </h1>
88 <p>On peut récupérer des nœuds texte dans le document source au
89 moyen de la balise <tt><xsl:value-of select="<a>xpath
90 expr</a>"/></tt>. L'expression <tt><a>xpath expr</a></tt> est
91 évaluée et <a>convertie en chaîne de caractères</a> en suivant
92 les conversions d'XPath (voir cours 3).
95 <div class="sws-slide">
96 <h1>Itération avec <tt>xsl:for-each</tt></h1>
97 <p>La balise <code> <xsl:for-each select="xpath expr">
100 </code> évalue le corp de la boucle pour chaque nœud renvoyé par
101 l'expression <tt><a>xpath expr</a></tt>. À chaque itération
102 le nœud considéré devient le <a>nœud contexte</a> (i.e. celui
103 renvoyé par l'axe <tt>self::</tt>)</p>
105 <div class="sws-slide">
106 <h1>Itération ordonnée <tt>xsl:sort</tt></h1>
107 <p>On peut modifier l'ordre dans lequel les éléments sont
108 parcourus par une boucle <tt>xsl:for-each</tt> en utilisant
109 l'élément <code> <![CDATA[<xsl:sort select="expression"
111 data-type="text|number|qname"
112 order="ascending|descending"
113 case-order="upper-first|lower-first"/>
114 ]]></code> qui n'est valide que comme fils d'un <tt>xsl:for-each</tt>
115 ou <tt>xsl:apply-templates</tt></p>
117 <li><tt>select</tt> : expression XPath selon laquelle
119 <li><tt>lang</tt> : code de la <a>locale</a> selon laquelle
120 trier (par exemple en français, <tt>é</tt> est
121 avant <tt>f</tt>)</li>
122 <li><tt>data-type</tt> : types des données triées (text
123 (defaut), nombre ou élément XML (ordre du document utilisé
125 <li><tt>order</tt> : s'il faut trier en ordre croissant ou
127 <li><tt>case-order</tt> : lors d'un tri <a>text</a> si les
128 majuscules sont avant les minuscules (defaut) ou inversement</li>
131 <div class="sws-slide">
132 <h1>Conditionnelle simple avec <tt>xsl:if</tt></h1>
133 <p>On peut évaluer conditionnellement une portion de code XSLT
134 en la plaçant dans une balise:<code><![CDATA[ <xsl:if test="expression">
136 </xsl:if>]]> </code> Le résultat de l'expression est interprété
137 comme un booléen (selon les règles de conversion d'XPath). S'il
138 vaut vrai, le corp du <tt>xsl:if</tt> est exécuté.</p>
140 <div class="sws-slide">
141 <h1>Conditionnelle complexe avec <tt>xsl:choose</tt></h1>
142 <p>On peut écrire plusieurs portions de code, gardées par des
143 conditions distinctes
144 en les plaçant dans une balise:<code><![CDATA[ <xsl:choose >
145 <xsl:when test="cond 1"> code 1</xsl:when>
146 <xsl:when test="cond 2"> code 2</xsl:when>
147 <xsl:when test="cond 3"> code 3</xsl:when>
149 <xsl:otherwise> code sinon </xsl:otherwise>
150 </xsl:choose>]]> </code>
151 Les conditions <tt>xsl:when</tt> sont évaluées dans l'ordre et
152 le corp de la première valant vrai est exécuté. Si aucune
153 condition n'est vérifiée, le corp de
154 l'instruction <tt>xsl:otherwise</tt> est exécuté.
157 <div class="sws-slide">
158 <h1>Exemple simple (génération d'une page Web)</h1>
159 <p>On réutilise (encore) le fichier de recette:</p>
160 <code style="color:black;font-size:80%;position:relative;left:10%;"><![CDATA[
161 <!DOCTYPE recette SYSTEM "recette.dtd">
162 <recette difficulte="facile">
163 <title>Tiramisú</title>
165 <ingredient>mascarpone</ingredient>
166 <ingredient>oeufs</ingredient>
167 <ingredient>sucre</ingredient>
168 <ingredient>café</ingredient>
169 <ingredient>biscuits</ingredient>
173 <e num="1">Séparer les blancs des jaunes</e>
180 <div class="sws-slide">
181 <code style="color:black;font-size:80%;position:relative;left:10%;"><![CDATA[
182 <xsl:stylesheet version="1.0"
183 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
184 <xsl:template match="/">
187 <title>Ingrédients du ]]><u><xsl:value-of select="descendant::title" /></u><![CDATA[ </title>
190 <h1>Ingrédients du ]]><u><xsl:value-of select="descendant::title" /></u><![CDATA[ </h1>
192 ]]><u><xsl:for-each select="descendant::ingredient"></u>
193 <u><xsl:sort select="child::text()" /></u><![CDATA[
194 <li> ]]><u><xsl:value-of select="child::text()" /></u><![CDATA[ </li>
195 ]]><u></xsl:for-each></u><![CDATA[
197 <p>Étape]]><u><xsl:if test="count(descendant::e) &gt;1">s</xsl:if></u><![CDATA[</p>
199 ]]><u><xsl:apply-templates select="descendant::e"></u>
200 <u><xsl:sort select="@num" data-type="number"/></u>
201 <u></xsl:apply-templates></u><![CDATA[
206 <xsl:template match="e">
207 <li><xsl:value-of select="."/></li>
212 <h1>Utilisation avancée</h1>
213 <div class="sws-slide">
214 <h1>Nom d'attributs ou d'éléments dynamiques</h1>
215 <p>Il est fréquent de vouloir choisir <a>dynamiquement</a> les noms
216 des éléments. Par exemple :</p>
219 <xsl:when test="condition"> <b> </xsl:when>
220 <xsl:otherwise> <i> </xsl:otherwise>
223 .... code complexe pour calculer le texte ....
226 <xsl:when test="condition"> </b> </xsl:when>
227 <xsl:otherwise> </i> </xsl:otherwise>
230 <p class="sws-pause"><s>code incorrect </s>: les balises <tt><b></tt>
231 et <tt><i></tt> ne sont pas bien parenthésées</p>
233 <div class="sws-slide">
234 <h1>Solution naïve</h1>
235 <p>On peut dupliquer le code de manière à respecter les balises
236 ouvrantes/fermantes : </p>
239 <xsl:when test="condition">
241 .... code complexe pour calculer le texte ....
246 .... code complexe pour calculer le texte ....
251 <p><s>Inélégant et non-maintenable</s> : si on a 10 cas, on copie cole
252 10 fois le code complexe.</p>
254 <div class="sws-slide">
255 <h1>Nom d'attributs ou d'éléments dynamiques</h1>
256 <p>On a besoin : </p>
258 <li>de pouvoir stocker dans des « variables » le résultat d'une
260 <li>de pouvoir créer des éléments ou des attributs dont le nom est
263 <p><s>Problème</s> : XPath ne permet pas de définir des variables</p>
265 <div class="sws-slide">
266 <h1>Variables en XSLT (<tt>xsl:variable</tt>)</h1>
267 <p>Comme dans tout langage, on veut pouvoir évaluer <a>une
268 expression</a> et donner un <a>nom</a> au <a>résultat</a> pour
269 pouvoir le réutiliser plusieurs fois. En XSLT, on utilise la
270 balise <tt>xsl:variable</tt> :</p>
272 <xsl:variable name="result" select="count(descendant::foo)" />
274 Le document contient <xsl:value-of select="$result" /> éléments foo.
277 <li>L'attribut <tt>name</tt> est obligatoire et permet de définir le
278 nom de la variable</li>
279 <li>L'attribut <tt>select</tt> s'il est présent permet de définir le
281 <li>Au sein d'une expression XPath, on peut utiliser la
282 notation <tt>$x</tt> pour référencer le contenu de la
283 variable <tt>x</tt></li>
286 <div class="sws-slide">
287 <h1>Définitions complexes de variables</h1>
288 <p>On peut aussi donner du contenu à l'élément <tt>xsl:variable</tt>,
289 pour définir la valeur de la variable : </p>
291 <xsl:variable name="result">
293 <xsl:when test="…condition…">b</xsl:when>
294 <xsl:otherwise>i</xsl:otherwise>
299 <div class="sws-slide">
300 <h1>Portée des variables</h1>
301 <p>Les variables sont <s>non-modifiables</s> une fois définies. Elles
302 sont visibles par tous les éléments suivant la balise
303 fermante <tt></xsl:variable></tt> se trouvant avant la
304 fermeture de l'élément contenant la variable. Exemple : </p>
305 <code style="background:white;"><![CDATA[
306 <xsl:template match="x">
307 <xsl:variable name="total" select="count(descendant::text())" />
308 <!-- la variable total est visible à partir d'ici et
309 jusqu'au </xsl:template> -->
312 <xsl:for-each select="descendant::text()">
313 <p>texte <xsl:value-of select="position()" /> sur
314 <xsl:value-of select="$total" /> :
315 <xsl:value-of select="." />
322 <div class="sws-slide">
323 <h1>Création dynamique d'éléments ou d'attributs</h1>
324 <p>On peut utiliser les instructions <tt>xsl:element</tt>
325 et <tt>xsl:attribute</tt> pour créer des éléments et des attributs
326 dont le nom est calculé dynamiquement :
329 <xsl:element name="foo">
330 <xsl:attribute name="bar">baz</xsl:attribute>
334 <p>produira dans le document de sortie :</p>
335 <code><![CDATA[ <foo bar='baz'>
340 <div class="sws-slide">
341 <h1>Échappement d'expressions XPath dans les chaînes</h1>
342 <p>À part les attributs <tt>select</tt> et <tt>test</tt> de
343 certaines balises XSLT, les autres attributs sont <s>des chaines de
344 caractères</s>. On peut cependant intégrer des expressions XPath au
345 moyen d'accolades <tt>{ }</tt>
348 <a href="descendant::url/child::text()">Le site!</a>]]>
350 <p>Dans le code ci-dessus, <tt>href</tt> étant un attribut non
351 interprété (ce n'est pas une balise XSLT), le chemin XPath
352 apparaîtra dans le résultat (ce qu'on ne veut pas). On peut écrire
355 <a href="{descendant::url/child::text()}">Le site!</a>]]>
358 <div class="sws-slide">
359 <h1>Retour sur notre exemple</h1>
361 <xsl:variable name="nombalise">
363 <xsl:when test="condition">b</xsl:when>
364 <xsl:otherwise>i</xsl:otherwise>
368 <xsl:element name="{$nombalise}">
369 .... code complexe pour calculer le texte ....
372 <p><s>Attention</s> : il faut écrire <tt>{$nombalise}</tt> sinon le
373 processeur XSLT essayera de créer un
374 élément <tt><$nombalise></tt> ce qui est illégal (et
375 provoquera une erreur)</p>
377 <h1>Autres fonctionalités</h1>
378 <div class="sws-slide">
379 <h1>Spécifier le type de sortie</h1>
380 <p>On peut placer une balise <tt>xsl:output</tt> dans la balise racine
381 de la feuille de style (<tt>xsl:stylesheet</tt>)</p>
382 <code ><![CDATA[ <xsl:output
383 method="xml|html|text"
384 cdata-section-elements="namelist"
388 <ul><li><tt>method</tt> : décrit le type de fichier généré (XML
389 (defaut), HTML (plus permissif sur les balises non fermées),
391 <li><tt>cdata-section-elements</tt> : liste de nom de balises
392 séparées par des espaces. Dans ces balises, le contenu du texte
393 n'est pas interprété (<tt>></tt>, <tt><</tt> peuvent êtres
394 écrits directement)</li>
395 <li><tt>indent</tt> : si la sortie est du XML, indenter les balises
396 de manière lisible</li>
399 <div class="sws-slide">
400 <h1>Copie de texte et de nœuds </h1>
402 <li>La balise <tt><xsl:copy-of select='expression'></tt>
403 copie le résultat de l'expression XPath (qui peut être un nœud)
404 dans la sortie, avec ses attributs et son contenu</li>
405 <li>La balise <tt><xsl:text> ... </xsl:text></tt>
406 copie le texte tel quel (sans toucher aux blancs) dans la sortie</li>