aa49a92f2b361e178a30b48023302d8040cd08c6
[hacks/simpleWebSlides.git] / xpi / xpi_05.xhtml
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"
4 >
5 <html xmlns="http://www.w3.org/1999/xhtml" >
6   <head>
7     <title>XSLT (suite)</title>
8
9     <meta http-equiv="Content-Type"
10           content="text/html; charset=utf-8" />
11     <meta name="copyright"
12           content="Copyright &#169; 2013 Kim Nguyễn" />
13
14     <!-- Load jQuery -->
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>
18
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" />
23
24     <!-- Customize some templates and initialize -->
25     <style type="text/css">
26       .xml-tag { color: #00486c; }
27     </style>
28     <script type="text/javascript">
29       <![CDATA[
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;
33
34       //Ensures that we load SWS at the very end, after MathJax has
35       //been initialized
36
37       $(window).load(function () {
38        $(".inline-xml").each(function(i, elem)
39       {
40       var jelem = $(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'>&lt;");
45       code = code.replace (/>>>/g,"&gt;</span>");
46
47       jelem.html(code);
48       });
49   });
50
51       var checkSVG = function (o, i)
52       {
53             if (i >= 10 || SWS.Utils.isUndefined(o) || o == null) return;
54             var svg = o.getSVGDocument();
55             if (svg == null) {
56               setTimeout(function() { checkSVG(o, i+1); }, 200);
57             } else {
58          var alltext = $(svg).find("text");
59          alltext.css("font-family", "DIN");
60          alltext.css("font-size", "70%");
61
62             };
63       };
64       $(window).load(function() {
65       $("embed").ready(function() {
66          setTimeout(function() {
67          $("embed").each(function(i, o) { checkSVG(this,0);   });
68 }, 1000);
69         });
70      });
71       $(window).load(SWS.Presentation.init);
72
73         ]]>
74
75     </script>
76
77   </head>
78   <body>
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>
82       <h1>Cours 5</h1>
83       <a href="mailto:kn@lri.fr">kn@lri.fr</a>
84     </div>
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>&lt;xsl:value-of select="<a>xpath
90       expr</a>"/&gt;</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).
93       </p>
94     </div>
95     <div class="sws-slide">
96       <h1>Itération avec <tt>xsl:for-each</tt></h1>
97       <p>La balise <code>  &lt;xsl:for-each select="xpath expr"&gt;
98           <i>corp de boucle</i>
99   &lt;/xsl:for-each&gt;
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>
104     </div>
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"
110    lang="language-code"
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>
116       <ul>
117         <li><tt>select</tt> : expression XPath selon laquelle
118         trier</li>
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é
124         dans ce cas)</li>
125         <li><tt>order</tt> : s'il faut trier en ordre croissant ou
126         décroissant</li>
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>
129       </ul>
130     </div>
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">
135       ...
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>
139     </div>
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>
148        ...
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é.
155       </p>
156     </div>
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>
164 <ingredients>
165   <ingredient>mascarpone</ingredient>
166   <ingredient>oeufs</ingredient>
167   <ingredient>sucre</ingredient>
168   <ingredient>café</ingredient>
169   <ingredient>biscuits</ingredient>
170 </ingredients>
171 <duree>2h</duree>
172 <etapes>
173   <e num="1">Séparer les blancs des jaunes</e>
174   <e num="2">…</e>
175   …
176 </etapes>
177 </recette>
178 ]]></code>
179     </div>
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="/">
185      <html>
186        <head>
187           <title>Ingrédients du ]]><u>&lt;xsl:value-of select="descendant::title" /&gt;</u><![CDATA[ </title>
188        </head>
189        <body>
190          <h1>Ingrédients du ]]><u>&lt;xsl:value-of select="descendant::title" /&gt;</u><![CDATA[ </h1>
191          <ul>
192            ]]><u>&lt;xsl:for-each select="descendant::ingredient"&gt;</u>
193               <u>&lt;xsl:sort select="child::text()" /&gt;</u><![CDATA[
194              <li> ]]><u>&lt;xsl:value-of select="child::text()" /&gt;</u><![CDATA[ </li>
195            ]]><u>&lt;/xsl:for-each&gt;</u><![CDATA[
196          </ul>
197          <p>Étape]]><u>&lt;xsl:if test="count(descendant::e) &amp;gt;1"&gt;s&lt;/xsl:if&gt;</u><![CDATA[</p>
198          <ol>
199            ]]><u>&lt;xsl:apply-templates select="descendant::e"&gt;</u>
200               <u>&lt;xsl:sort select="@num" data-type="number"/&gt;</u>
201            <u>&lt;/xsl:apply-templates&gt;</u><![CDATA[
202          </ol>
203        </body>
204      </html>
205    </xsl:template>
206    <xsl:template match="e">
207      <li><xsl:value-of select="."/></li>
208    </xsl:template>
209   </xsl:stylesheet>
210 ]]></code>
211     </div>
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>
217 <code><![CDATA[
218   <xsl:choose>
219     <xsl:when test="condition"> <b> </xsl:when>
220     <xsl:otherwise>  <i> </xsl:otherwise>
221   </xsl:choose>
222
223     .... code complexe pour calculer le texte ....
224
225    <xsl:choose>
226     <xsl:when test="condition"> </b> </xsl:when>
227     <xsl:otherwise>  </i> </xsl:otherwise>
228   </xsl:choose>]]>
229 </code>
230 <p class="sws-pause"><s>code incorrect </s>: les balises <tt>&lt;b&gt;</tt>
231 et <tt>&lt;i&gt;</tt> ne sont pas bien parenthésées</p>
232 </div>
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>
237 <code><![CDATA[
238   <xsl:choose>
239     <xsl:when test="condition">
240       <b>
241             .... code complexe pour calculer le texte ....
242       </b>
243     </xsl:when>
244     <xsl:otherwise>
245       <i>
246             .... code complexe pour calculer le texte ....
247       </i>
248       </xsl:otherwise>
249   </xsl:choose>]]>
250 </code>
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>
253 </div>
254 <div class="sws-slide">
255 <h1>Nom d'attributs ou d'éléments dynamiques</h1>
256 <p>On a besoin : </p>
257 <ul>
258   <li>de pouvoir stocker dans des « variables » le résultat d'une
259   expression XSLT</li>
260   <li>de pouvoir créer des éléments ou des attributs dont le nom est
261   une expression</li>
262 </ul>
263 <p><s>Problème</s> : XPath ne permet pas de définir des variables</p>
264 </div>
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>
271 <code><![CDATA[
272   <xsl:variable name="result" select="count(descendant::foo)" />
273
274   Le document contient <xsl:value-of select="$result" /> éléments foo.
275 ]]></code>
276 <ul>
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
280   contenu</li>
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>
284 </ul>
285 </div>
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>
290 <code><![CDATA[
291   <xsl:variable name="result">
292     <xsl:choose>
293       <xsl:when test="…condition…">b</xsl:when>
294       <xsl:otherwise>i</xsl:otherwise>
295     </xsl:choose>
296   </xsl:variable>]]>
297 </code>
298 </div>
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>&lt;/xsl:variable&gt;</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> -->
310
311
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="." />
316     </p>
317   </xsl:for-each>
318
319 </xsl:template>]]>
320 </code>
321 </div>
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 :
327 </p>
328 <code><![CDATA[
329   <xsl:element name="foo">
330     <xsl:attribute name="bar">baz</xsl:attribute>
331     ...
332   </xsl:element>
333 ]]></code>
334 <p>produira dans le document de sortie :</p>
335 <code><![CDATA[  <foo bar='baz'>
336    ...
337   </foo>
338 ]]></code>
339 </div>
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>
346   </p>
347   <code><![CDATA[
348     <a href="descendant::url/child::text()">Le site!</a>]]>
349   </code>
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
353   :</p>
354   <code><![CDATA[
355     <a href="{descendant::url/child::text()}">Le site!</a>]]>
356   </code>
357 </div>
358 <div class="sws-slide">
359 <h1>Retour sur notre exemple</h1>
360 <code><![CDATA[
361   <xsl:variable name="nombalise">
362     <xsl:choose>
363      <xsl:when test="condition">b</xsl:when>
364      <xsl:otherwise>i</xsl:otherwise>
365     </xsl:choose>
366   </xsl:variable>
367
368   <xsl:element name="{$nombalise}">
369       .... code complexe pour calculer le texte ....
370   </xsl:element>
371 ]]></code>
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>&lt;$nombalise&gt;</tt> ce qui est illégal (et
375   provoquera une erreur)</p>
376 </div>
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"
385       indent="yes|no"
386    />
387 ]]></code>
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),
390     texte)</li>
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>&gt;</tt>, <tt>&lt;</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>
397 </ul>
398 </div>
399 <div class="sws-slide">
400   <h1>Copie de texte et de nœuds </h1>
401   <ul>
402     <li>La balise <tt>&lt;xsl:copy-of select='expression'&gt;</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>&lt;xsl:text&gt; ... &lt;/xsl:text&gt;</tt>
406     copie le texte tel quel (sans toucher aux blancs) dans la sortie</li>
407   </ul>
408 </div>
409   </body>
410 </html>