--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+>
+<html xmlns="http://www.w3.org/1999/xhtml" >
+ <head>
+ <title>XSLT (suite)</title>
+
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=utf-8" />
+ <meta name="copyright"
+ content="Copyright © 2013 Kim Nguyễn" />
+
+ <!-- Load jQuery -->
+ <script src="../jquery-1.9.1.min.js" type="text/javascript" ></script>
+ <!-- Load the library -->
+ <script src="../simpleWebSlides.js" type="text/javascript" ></script>
+
+ <link rel="stylesheet" href="../simpleWebSlides.css" type="text/css" media="all" />
+ <!-- Load a custom Theme, the class-element marks this style-sheet
+ a "theme" that can be swtiched dynamicaly -->
+ <link class="sws-theme" rel="stylesheet" title="U-Psud style" href="../themes/uPsud.css" type="text/css" />
+
+ <!-- Customize some templates and initialize -->
+ <style type="text/css">
+ .xml-tag { color: #00486c; }
+ </style>
+ <script type="text/javascript">
+ <![CDATA[
+ SWS.Config['sws-slide-change'] = SWS.Effects.slideChangeFadeOutIn;
+ SWS.Config['sws-object-deactivate'] = SWS.Effects.objectDeactivateFadeOut;
+ SWS.Config['sws-object-activate'] = SWS.Effects.objectActivateFadeIn;
+
+ //Ensures that we load SWS at the very end, after MathJax has
+ //been initialized
+
+ $(window).load(function () {
+ $(".inline-xml").each(function(i, elem)
+ {
+ var jelem = $(elem);
+ var code = jelem.html();
+ code = code.replace ("<![CDATA" + "[", "").replace ("]" + "]>", "");
+ code = code.replace (/>/g, ">>>");
+ code = code.replace (/</g, "<span class='xml-tag'><");
+ code = code.replace (/>>>/g,"></span>");
+
+ jelem.html(code);
+ });
+ });
+
+ var checkSVG = function (o, i)
+ {
+ if (i >= 10 || SWS.Utils.isUndefined(o) || o == null) return;
+ var svg = o.getSVGDocument();
+ if (svg == null) {
+ setTimeout(function() { checkSVG(o, i+1); }, 200);
+ } else {
+ var alltext = $(svg).find("text");
+ alltext.css("font-family", "DIN");
+ alltext.css("font-size", "70%");
+
+ };
+ };
+ $(window).load(function() {
+ $("embed").ready(function() {
+ setTimeout(function() {
+ $("embed").each(function(i, o) { checkSVG(this,0); });
+}, 1000);
+ });
+ });
+ $(window).load(SWS.Presentation.init);
+
+ ]]>
+
+ </script>
+
+ </head>
+ <body>
+ <a href="xpi_04.xhtml" class="sws-previous"/>
+ <div class="sws-slide sws-cover sws-option-nofooter">
+ <h1>XML et Programmation Internet</h1>
+ <h1>Cours 5</h1>
+ <a href="mailto:kn@lri.fr">kn@lri.fr</a>
+ </div>
+ <h1>Structures de contrôle</h1>
+ <div class="sws-slide">
+ <h1><tt>xsl:value-of</tt> </h1>
+ <p>On peut récupérer des nœuds texte dans le document source au
+ moyen de la balise <tt><xsl:value-of select="<a>xpath
+ expr</a>"/></tt>. L'expression <tt><a>xpath expr</a></tt> est
+ évaluée et <a>convertie en chaîne de caractères</a> en suivant
+ les conversions d'XPath (voir cours 3).
+ </p>
+ </div>
+ <div class="sws-slide">
+ <h1>Itération avec <tt>xsl:for-each</tt></h1>
+ <p>La balise <code> <xsl:for-each select="xpath expr">
+ <i>corp de boucle</i>
+ </xsl:for-each>
+</code> évalue le corp de la boucle pour chaque nœud renvoyé par
+ l'expression <tt><a>xpath expr</a></tt>. À chaque itération
+ le nœud considéré devient le <a>nœud contexte</a> (i.e. celui
+ renvoyé par l'axe <tt>self::</tt>)</p>
+ </div>
+ <div class="sws-slide">
+ <h1>Itération ordonnée <tt>xsl:sort</tt></h1>
+ <p>On peut modifier l'ordre dans lequel les éléments sont
+ parcourus par une boucle <tt>xsl:for-each</tt> en utilisant
+ l'élément <code> <![CDATA[<xsl:sort select="expression"
+ lang="language-code"
+ data-type="text|number|qname"
+ order="ascending|descending"
+ case-order="upper-first|lower-first"/>
+]]></code> qui n'est valide que comme fils d'un <tt>xsl:for-each</tt>
+ ou <tt>xsl:apply-templates</tt></p>
+ <ul>
+ <li><tt>select</tt> : expression XPath selon laquelle
+ trier</li>
+ <li><tt>lang</tt> : code de la <a>locale</a> selon laquelle
+ trier (par exemple en français, <tt>é</tt> est
+ avant <tt>f</tt>)</li>
+ <li><tt>data-type</tt> : types des données triées (text
+ (defaut), nombre ou élément XML (ordre du document utilisé
+ dans ce cas)</li>
+ <li><tt>order</tt> : s'il faut trier en ordre croissant ou
+ décroissant</li>
+ <li><tt>case-order</tt> : lors d'un tri <a>text</a> si les
+ majuscules sont avant les minuscules (defaut) ou inversement</li>
+ </ul>
+ </div>
+ <div class="sws-slide">
+ <h1>Conditionnelle simple avec <tt>xsl:if</tt></h1>
+ <p>On peut évaluer conditionnellement une portion de code XSLT
+ en la plaçant dans une balise:<code><![CDATA[ <xsl:if test="expression">
+ ...
+ </xsl:if>]]> </code> Le résultat de l'expression est interprété
+ comme un booléen (selon les règles de conversion d'XPath). S'il
+ vaut vrai, le corp du <tt>xsl:if</tt> est exécuté.</p>
+ </div>
+ <div class="sws-slide">
+ <h1>Conditionnelle complexe avec <tt>xsl:choose</tt></h1>
+ <p>On peut écrire plusieurs portions de code, gardées par des
+ conditions distinctes
+ en les plaçant dans une balise:<code><![CDATA[ <xsl:choose >
+ <xsl:when test="cond 1"> code 1</xsl:when>
+ <xsl:when test="cond 2"> code 2</xsl:when>
+ <xsl:when test="cond 3"> code 3</xsl:when>
+ ...
+ <xsl:otherwise> code sinon </xsl:otherwise>
+ </xsl:choose>]]> </code>
+ Les conditions <tt>xsl:when</tt> sont évaluées dans l'ordre et
+ le corp de la première valant vrai est exécuté. Si aucune
+ condition n'est vérifiée, le corp de
+ l'instruction <tt>xsl:otherwise</tt> est exécuté.
+ </p>
+ </div>
+ <div class="sws-slide">
+ <h1>Exemple simple (génération d'une page Web)</h1>
+ <p>On réutilise (encore) le fichier de recette:</p>
+ <code style="color:black;font-size:80%;position:relative;left:10%;"><![CDATA[
+<!DOCTYPE recette SYSTEM "recette.dtd">
+<recette difficulte="facile">
+<title>Tiramisú</title>
+<ingredients>
+ <ingredient>mascarpone</ingredient>
+ <ingredient>oeufs</ingredient>
+ <ingredient>sucre</ingredient>
+ <ingredient>café</ingredient>
+ <ingredient>biscuits</ingredient>
+</ingredients>
+<duree>2h</duree>
+<etapes>
+ <e num="1">Séparer les blancs des jaunes</e>
+ <e num="2">…</e>
+ …
+</etapes>
+</recette>
+]]></code>
+ </div>
+ <div class="sws-slide">
+ <code style="color:black;font-size:80%;position:relative;left:10%;"><![CDATA[
+ <xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ <xsl:template match="/">
+ <html>
+ <head>
+ <title>Ingrédients du ]]><u><xsl:value-of select="descendant::title" /></u><![CDATA[ </title>
+ </head>
+ <body>
+ <h1>Ingrédients du ]]><u><xsl:value-of select="descendant::title" /></u><![CDATA[ </h1>
+ <ul>
+ ]]><u><xsl:for-each select="descendant::ingredient"></u>
+ <u><xsl:sort select="child::text()" /></u><![CDATA[
+ <li> ]]><u><xsl:value-of select="child::text()" /></u><![CDATA[ </li>
+ ]]><u></xsl:for-each></u><![CDATA[
+ </ul>
+ <p>Étape]]><u><xsl:if test="count(descendant::e) &gt;1">s</xsl:if></u><![CDATA[</p>
+ <ol>
+ ]]><u><xsl:apply-templates select="descendant::e"></u>
+ <u><xsl:sort select="@num" data-type="number"/></u>
+ <u></xsl:apply-templates></u><![CDATA[
+ </ol>
+ </body>
+ </html>
+ </xsl:template>
+ <xsl:template match="e">
+ <li><xsl:value-of select="."/></li>
+ </xsl:template>
+ </xsl:stylesheet>
+]]></code>
+ </div>
+<h1>Utilisation avancée</h1>
+<div class="sws-slide">
+ <h1>Nom d'attributs ou d'éléments dynamiques</h1>
+ <p>Il est fréquent de vouloir choisir <a>dynamiquement</a> les noms
+ des éléments. Par exemple :</p>
+<code><![CDATA[
+ <xsl:choose>
+ <xsl:when test="condition"> <b> </xsl:when>
+ <xsl:otherwise> <i> </xsl:otherwise>
+ </xsl:choose>
+
+ .... code complexe pour calculer le texte ....
+
+ <xsl:choose>
+ <xsl:when test="condition"> </b> </xsl:when>
+ <xsl:otherwise> </i> </xsl:otherwise>
+ </xsl:choose>]]>
+</code>
+<p class="sws-pause"><s>code incorrect </s>: les balises <tt><b></tt>
+et <tt><i></tt> ne sont pas bien parenthésées</p>
+</div>
+<div class="sws-slide">
+<h1>Solution naïve</h1>
+<p>On peut dupliquer le code de manière à respecter les balises
+ ouvrantes/fermantes : </p>
+<code><![CDATA[
+ <xsl:choose>
+ <xsl:when test="condition">
+ <b>
+ .... code complexe pour calculer le texte ....
+ </b>
+ </xsl:when>
+ <xsl:otherwise>
+ <i>
+ .... code complexe pour calculer le texte ....
+ </i>
+ </xsl:otherwise>
+ </xsl:choose>]]>
+</code>
+<p><s>Inélégant et non-maintenable</s> : si on a 10 cas, on copie cole
+ 10 fois le code complexe.</p>
+</div>
+<div class="sws-slide">
+<h1>Nom d'attributs ou d'éléments dynamiques</h1>
+<p>On a besoin : </p>
+<ul>
+ <li>de pouvoir stocker dans des « variables » le résultat d'une
+ expression XSLT</li>
+ <li>de pouvoir créer des éléments ou des attributs dont le nom est
+ une expression</li>
+</ul>
+<p><s>Problème</s> : XPath ne permet pas de définir des variables</p>
+</div>
+<div class="sws-slide">
+ <h1>Variables en XSLT (<tt>xsl:variable</tt>)</h1>
+ <p>Comme dans tout langage, on veut pouvoir évaluer <a>une
+ expression</a> et donner un <a>nom</a> au <a>résultat</a> pour
+ pouvoir le réutiliser plusieurs fois. En XSLT, on utilise la
+ balise <tt>xsl:variable</tt> :</p>
+<code><![CDATA[
+ <xsl:variable name="result" select="count(descendant::foo)" />
+
+ Le document contient <xsl:value-of select="$result" /> éléments foo.
+]]></code>
+<ul>
+ <li>L'attribut <tt>name</tt> est obligatoire et permet de définir le
+ nom de la variable</li>
+ <li>L'attribut <tt>select</tt> s'il est présent permet de définir le
+ contenu</li>
+ <li>Au sein d'une expression XPath, on peut utiliser la
+ notation <tt>$x</tt> pour référencer le contenu de la
+ variable <tt>x</tt></li>
+</ul>
+</div>
+<div class="sws-slide">
+<h1>Définitions complexes de variables</h1>
+<p>On peut aussi donner du contenu à l'élément <tt>xsl:variable</tt>,
+ pour définir la valeur de la variable : </p>
+<code><![CDATA[
+ <xsl:variable name="result">
+ <xsl:choose>
+ <xsl:when test="…condition…">b</xsl:when>
+ <xsl:otherwise>i</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>]]>
+</code>
+</div>
+<div class="sws-slide">
+<h1>Portée des variables</h1>
+<p>Les variables sont <s>non-modifiables</s> une fois définies. Elles
+ sont visibles par tous les éléments suivant la balise
+ fermante <tt></xsl:variable></tt> se trouvant avant la
+ fermeture de l'élément contenant la variable. Exemple : </p>
+<code style="background:white;"><![CDATA[
+<xsl:template match="x">
+ <xsl:variable name="total" select="count(descendant::text())" />
+ <!-- la variable total est visible à partir d'ici et
+ jusqu'au </xsl:template> -->
+
+
+ <xsl:for-each select="descendant::text()">
+ <p>texte <xsl:value-of select="position()" /> sur
+ <xsl:value-of select="$total" /> :
+ <xsl:value-of select="." />
+ </p>
+ </xsl:for-each>
+
+</xsl:template>]]>
+</code>
+</div>
+<div class="sws-slide">
+<h1>Création dynamique d'éléments ou d'attributs</h1>
+<p>On peut utiliser les instructions <tt>xsl:element</tt>
+ et <tt>xsl:attribute</tt> pour créer des éléments et des attributs
+ dont le nom est calculé dynamiquement :
+</p>
+<code><![CDATA[
+ <xsl:element name="foo">
+ <xsl:attribute name="bar">baz</xsl:attribute>
+ ...
+ </xsl:element>
+]]></code>
+<p>produira dans le document de sortie :</p>
+<code><![CDATA[ <foo bar='baz'>
+ ...
+ </foo>
+]]></code>
+</div>
+<div class="sws-slide">
+ <h1>Échappement d'expressions XPath dans les chaînes</h1>
+ <p>À part les attributs <tt>select</tt> et <tt>test</tt> de
+ certaines balises XSLT, les autres attributs sont <s>des chaines de
+ caractères</s>. On peut cependant intégrer des expressions XPath au
+ moyen d'accolades <tt>{ }</tt>
+ </p>
+ <code><![CDATA[
+ <a href="descendant::url/child::text()">Le site!</a>]]>
+ </code>
+ <p>Dans le code ci-dessus, <tt>href</tt> étant un attribut non
+ interprété (ce n'est pas une balise XSLT), le chemin XPath
+ apparaîtra dans le résultat (ce qu'on ne veut pas). On peut écrire
+ :</p>
+ <code><![CDATA[
+ <a href="{descendant::url/child::text()}">Le site!</a>]]>
+ </code>
+</div>
+<div class="sws-slide">
+<h1>Retour sur notre exemple</h1>
+<code><![CDATA[
+ <xsl:variable name="nombalise">
+ <xsl:choose>
+ <xsl:when test="condition">b</xsl:when>
+ <xsl:otherwise>i</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:element name="{$nombalise}">
+ .... code complexe pour calculer le texte ....
+ </xsl:element>
+]]></code>
+<p><s>Attention</s> : il faut écrire <tt>{$nombalise}</tt> sinon le
+ processeur XSLT essayera de créer un
+ élément <tt><$nombalise></tt> ce qui est illégal (et
+ provoquera une erreur)</p>
+</div>
+<h1>Autres fonctionalités</h1>
+<div class="sws-slide">
+<h1>Spécifier le type de sortie</h1>
+<p>On peut placer une balise <tt>xsl:output</tt> dans la balise racine
+ de la feuille de style (<tt>xsl:stylesheet</tt>)</p>
+<code ><![CDATA[ <xsl:output
+ method="xml|html|text"
+ cdata-section-elements="namelist"
+ indent="yes|no"
+ />
+]]></code>
+<ul><li><tt>method</tt> : décrit le type de fichier généré (XML
+ (defaut), HTML (plus permissif sur les balises non fermées),
+ texte)</li>
+ <li><tt>cdata-section-elements</tt> : liste de nom de balises
+ séparées par des espaces. Dans ces balises, le contenu du texte
+ n'est pas interprété (<tt>></tt>, <tt><</tt> peuvent êtres
+ écrits directement)</li>
+ <li><tt>indent</tt> : si la sortie est du XML, indenter les balises
+ de manière lisible</li>
+</ul>
+</div>
+<div class="sws-slide">
+ <h1>Copie de texte et de nœuds </h1>
+ <ul>
+ <li>La balise <tt><xsl:copy-of select='expression'></tt>
+ copie le résultat de l'expression XPath (qui peut être un nœud)
+ dans la sortie, avec ses attributs et son contenu</li>
+ <li>La balise <tt><xsl:text> ... </xsl:text></tt>
+ copie le texte tel quel (sans toucher aux blancs) dans la sortie</li>
+ </ul>
+</div>
+ </body>
+</html>