Add XPI lecture 3
authorKim Nguyễn <kn@lri.fr>
Mon, 22 Sep 2014 20:26:01 +0000 (22:26 +0200)
committerKim Nguyễn <kn@lri.fr>
Mon, 22 Sep 2014 20:26:01 +0000 (22:26 +0200)
xpi/pdf/xpi_03.pdf [new file with mode: 0644]
xpi/pdf/xpi_03_print.pdf [new file with mode: 0644]
xpi/xpi_03.xhtml [new file with mode: 0644]

diff --git a/xpi/pdf/xpi_03.pdf b/xpi/pdf/xpi_03.pdf
new file mode 100644 (file)
index 0000000..5584f20
Binary files /dev/null and b/xpi/pdf/xpi_03.pdf differ
diff --git a/xpi/pdf/xpi_03_print.pdf b/xpi/pdf/xpi_03_print.pdf
new file mode 100644 (file)
index 0000000..8886900
Binary files /dev/null and b/xpi/pdf/xpi_03_print.pdf differ
diff --git a/xpi/xpi_03.xhtml b/xpi/xpi_03.xhtml
new file mode 100644 (file)
index 0000000..2e5d601
--- /dev/null
@@ -0,0 +1,440 @@
+<?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>XPath (suite)</title>
+
+    <meta http-equiv="Content-Type"
+          content="text/html; charset=utf-8" />
+    <meta name="copyright"
+          content="Copyright &#169; 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'>&lt;");
+      code = code.replace (/>>>/g,"&gt;</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_02.xhtml" class="sws-previous"/>
+    <div class="sws-slide sws-cover sws-option-nofooter">
+      <h1>XML et Programmation Internet</h1>
+      <h1>Cours 3</h1>
+      <a href="mailto:kn@lri.fr">kn@lri.fr</a>
+    </div>
+    <h1>Évaluation des prédicats</h1>
+    <div class="sws-slide">
+      <h1>Rappels de syntaxe</h1>
+<code>
+      p ::=   p or p
+         |    p and p
+         |    not (p)
+         |    count(…), contains(…), position(), …
+         |    chemin XPath
+         |    e<sub>1</sub> op e<sub>2</sub>
+</code>
+<p>On évalue le prédicat et on converti son résultat en valeur de
+  vérité. Si la valeur vaut vrai, on garde le nœud courant, si elle
+  vaut faux, on ne le garde pas
+</p>
+<p>XPath connait <a>4 types de données</a> pour les prédicats : </p>
+<ul>
+<li>Les booléens, valeur de vérité : vrai ou faux</li>
+<li>Les nombres (flottants), valeur de vérité compliquée… </li>
+<li>Les chaînes de caractères, chaîne vide = faux, sinon vrai</li>
+<li>Les ensembles de nœuds, ensemble vide = faux, sinon vrai </li>
+</ul>
+    </div>
+<div class="sws-slide">
+<h1>Comparaisons (e<sub>1</sub> op e<sub>2</sub>)</h1>
+<p> Les opérateurs de comparaisons sont : <tt>=, !=, &lt;, &lt;=,
+    &gt;, &gt;= </tt>.<br/>
+  La manière de calculer de vérité de <tt>e<sub>1</sub> op
+    e<sub>2</sub></tt> dépend du typed de <tt>e<sub>1</sub></tt>
+    et  <tt>e<sub>2</sub></tt> :
+</p>
+<ul>
+  <li>Si  <tt>e<sub>1</sub></tt> et  <tt>e<sub>2</sub></tt> représente
+    <a>des ensembles de nœuds</a>, alors la comparaison est vraie ssi
+    il existe un élément <tt>x</tt> dans <tt>e<sub>1</sub></tt> et un
+    élément <tt>y</tt> dans <tt>e<sub>2</sub></tt> tels que <tt>x&nbsp;op&nbsp;y</tt>
+  </li>
+
+  <li>Si  <tt>e<sub>1</sub></tt> représente
+    <a>un ensembles de nœuds</a> et <tt>e<sub>2</sub></tt> une valeur
+    scalaire <tt>y</tt>, alors la comparaison est vraie ssi
+    il existe un élément <tt>x</tt> dans <tt>e<sub>1</sub></tt> tel que <tt>x&nbsp;op&nbsp;y</tt>
+  </li>
+  <li>Si <tt>e<sub>1</sub></tt> et  <tt>e<sub>2</sub></tt> sont des
+  valeurs scalaires, alors ont les compare en utilisant les règles de
+  comparaison des valeurs scalaires (voir page suivante).
+  </li>
+</ul>
+</div>
+<div class="sws-slide">
+<h1>Comparaisons des valeurs scalaires</h1>
+<code>                                  v<sub>1</sub> op v<sub>2</sub> </code>
+<p>Si op est <tt>!=</tt> ou <tt>=</tt>, on applique les règles dans cet ordre:</p>
+<ol>
+<li> Si <tt>v<sub>1</sub></tt> (resp. <tt>v<sub>2</sub></tt>) est
+  un <a>booléen</a>, alors <tt>v<sub>2</sub></tt>
+  (resp. <tt>v<sub>1</sub></tt>) est converti en booléen et les deux
+  booléens sont comparés </li>
+<li> Sinon si <tt>v<sub>1</sub></tt> (resp. <tt>v<sub>2</sub></tt>) est
+  un <a>nombre</a>, alors <tt>v<sub>2</sub></tt>
+  (resp. <tt>v<sub>1</sub></tt>) est converti en nombre et les deux
+  nombres sont comparés </li>
+<li> Sinon, <tt>v<sub>1</sub></tt> et <tt>v<sub>2</sub></tt> sont des
+  <a>chaines de caractères</a>, on les compares</li>
+</ol>
+<p>Si op est <tt> &lt;</tt>,  <tt> &lt;=</tt>,  <tt> &gt;</tt> ou <tt>
+    &gt;=</tt>, on convertit <tt>v<sub>1</sub></tt>
+    et <tt>v<sub>2</sub></tt> en <a>nombres</a> et on les compare.
+</p>
+</div>
+<div class="sws-slide">
+<h1>Conversions</h1>
+<p>Conversion en booléen</p>
+<ul>
+  <li>0 et NaN sont converti en <tt>false</tt>, le reste
+  en <tt>true</tt> </li>
+  <li>Un ensemble de nœud vaut <tt>true</tt> ssi il est non vide</li>
+  <li>Une chaine vaut <tt>true</tt> ssi elle est non vide</li>
+</ul>
+<p>Conversion en nombre</p>
+<ul>
+  <li>Une chaine de caractère représentant un flottant au format
+  IEEE-754 est convertie en ce nombre, sinon elle est convertie en NaN
+  </li>
+  <li>Booléen: <tt>true</tt> est converti à 1, <tt>false</tt> est
+  converti à 0</li>
+  <li>Un ensemble de nœud est d'abord converti en chaine de caractères
+  puis la chaine est convertie en nombre</li>
+</ul>
+</div>
+<div class="sws-slide">
+<h1>Conversions (suite)</h1>
+<p>Conversion en chaine de caractères</p>
+<ul>
+  <li>Un booléen est traduit en <tt>"true"</tt> ou <tt>"false"</tt>
+  selon sa valeur</li>
+  <li>Nombres:
+    <ul><li>NaN est converti en la chaine <tt>"NaN"</tt></li>
+      <li>Si le nombre n'a pas de partie décimale, sa
+      représentation <i>entière</i> est convertie en chaine (ex:
+      1.000e10 ≡ <tt>"10"</tt>)</li>
+      <li>Sinon une représentation IEE-754 du nombre est utilisé
+      (ex: <tt>"123.10e-34"</tt>)
+       </li>
+    </ul>
+  </li>
+  <li>Ensemble de noœud : <ul>
+      <li>L'ensemble vide est converti en la chaine vide
+      </li>
+      <li>Sinon le premier élément dans l'ordre du document est
+      converti en chaine en concatenant tous les nœuds textes dans ces
+      descendants (y compris lui-même)</li>
+    </ul>
+  </li>
+</ul>
+</div>
+
+<div class="sws-slide">
+<h1>Appels de fonction</h1>
+<p>Il existe des fonctions prédéfinies (voir la spec XPath)</p>
+<ul>
+  <li><tt>contains(str<sub>1</sub>,str<sub>2</sub>)</tt></li>
+  <li><tt>starts-with(str<sub>1</sub>,str<sub>2</sub>)</tt></li>
+  <li><tt>count(node_set<sub>1</sub>)</tt></li>
+  <li><tt>last()</tt></li>
+  <li><tt>position()</tt></li>
+  <li>…</li>
+</ul>
+<p>Si les arguments ne sont pas du bon type, ils sont convertis en
+  utilisant les règles de conversion</p>
+</div>
+<div class="sws-slide">
+<h1>Exemples</h1>
+<p>Dans la suite, on se donne un document de test ayant une
+  racine <tt><![CDATA[<a> ... </a>]]></tt> et une expression XPath qui
+  sélectionne la racine si et seulement si le prédicat vaut vrai
+</p>
+</div>
+<div class="sws-slide">
+  <h1>Exemples</h1>
+  <code>        <![CDATA[ <a>
+           <b>1</b>
+           <c>2</c>
+         </a> ]]></code>
+<ol> <li class="sws-pause">
+    <tt>/child::a[ child::*/child::text() ]</tt>
+    <span class="sws-pause">sélectionne la racine (l'ensemble de nœud
+    renvoyé par <tt>child::*/cild::text()</tt> est non vide, donc il est converti
+    en <tt>true</tt>)</span><br/><br/></li>
+ <li class="sws-pause">
+    <tt>/child::a[ child::*/child::text() = "2" ]</tt>
+    <span class="sws-pause">sélectionne la racine (l'ensemble de nœud texte
+    renvoyé par <tt>child::*/child::text()</tt> est comparé à "2", et
+    il existe un élément dans cet ensemble pour lequel le test réussi
+    )</span><br/><br/></li>
+  <li class="sws-pause"><tt>/child::a[ child::*/child::text() != "2" ]</tt>
+    <span class="sws-pause"><s>sélectionne la racine</s> (l'ensemble de nœud texte
+      renvoyé par <tt>child::*/child::text()</tt> est comparé à "2", et
+      il existe un élément dans cet ensemble pour lequel le test réussi
+      )</span><br/><br/></li>
+  <li class="sws-pause" style="background:white;"><tt>/child::a[ not(child::*/child::text() = "2") ]</tt>
+    <span class="sws-pause"><s>ne sélectionne pas la racine</s> (on
+      prend la négation du deuxième cas ci-dessus)
+    </span><br/><br/></li>
+
+</ol>
+</div>
+<div class="sws-slide">
+  <h1>Exemples</h1>
+  <code>        <![CDATA[ <a>
+           <b>1</b><b>2</b>
+           <c>2</c><c>3</c>
+         </a> ]]></code>
+<ol>
+ <li class="sws-pause">
+    <tt>/child::a[ child::*/child::text() &gt; 1.5 ]</tt>
+    <span class="sws-pause">sélectionne la racine (l'ensemble de nœud texte
+    renvoyé par <tt>child::*/child::text()</tt> est comparé à 1.5, et
+    il existe un élément dans cet ensemble pour lequel le test réussi
+    )</span><br/><br/></li>
+  <li class="sws-pause"><tt>/child::a[ child::b/child::text() &gt;= child::c/child::text() ]</tt>
+    <span class="sws-pause"><s>sélectionne la racine</s> (les deux
+      ensembles de nœuds sont convertis en ensmbles de nombres, car on
+      utilise <tt>&gt;=</tt> et on a bien que <tt>2 &gt;= 2</tt>
+      )</span><br/><br/></li>
+  <li class="sws-pause"><tt>/child::a[ child::b/child::text() = child::c/child::text() ]</tt>
+    <span class="sws-pause"><s>sélectionne la racine</s> (les deux
+      ensembles de nœuds comportent un élément commun)</span><br/><br/></li>
+  <li class="sws-pause"><tt>/child::a[ child::b/child::text() != child::c/child::text() ]</tt>
+    <span class="sws-pause"><s>sélectionne la racine</s> (les deux
+      comportent des éléments différents)</span><br/><br/></li>
+</ol>
+</div>
+<div class="sws-slide">
+  <h1>Exemples</h1>
+  <code>                   <![CDATA[ <a><b>1</b><b>2</b><c>2</c><c>3</c></a> ]]></code>
+<ol>
+ <li class="sws-pause">
+    <tt>/child::a[ contains(self::*, "22") ]</tt>
+    <span class="sws-pause"><s>sélectionne la racine</s>(l'ensemble de
+    nœud séléctionné par <tt>self::*</tt>, i.e. la racine est converti
+    en chaine. Pour ce faire, on colle toutes éléments textes
+    descendants et on obtient la chaine "1223" qui contient bien "22")
+    </span><br/><br/></li>
+ <li class="sws-pause">
+    <tt>/child::a[ self::* > 442.38 ]</tt>
+    <span class="sws-pause"><s>sélectionne la racine</s>(l'ensemble de
+    nœud séléctionné par <tt>self::*</tt>, est converti en chaine puis
+    en nombre pour comparer 1223 à 442.38)
+    </span><br/><br/></li>
+
+ <li class="sws-pause">
+    <tt>/child::a[ sum(child::*) &gt;= 7.5 ]</tt>
+    <span class="sws-pause"><s>sélectionne la racine</s>(la fonction
+    <tt>sum</tt> converti la liste de valeurs passée en argument en
+    liste de nombre et fait la somme de ces derniers)
+    </span><br/><br/></li>
+</ol>
+</div>
+
+<div class="sws-slide">
+  <h1>Exemples</h1>
+  <code>                   <![CDATA[ <a><b>1</b><b>toto</b><c>2</c><c>3</c></a> ]]></code>
+<ol>
+
+ <li class="sws-pause">
+    <tt>/child::a[ sum(child::*) &gt;= 7.5 ]</tt>
+    <span class="sws-pause"><s>ne sélectionne pas la racine</s>(la fonction
+    <tt>sum</tt> converti la liste de valeurs passée en argument en
+    liste de nombres, toto n'étant pas un nombre valide, il est
+    remplacé par NaN. La somme totale fait donc NaN, et une
+    comparaison avec NaN renvoie toujours faux)
+    </span><br/><br/></li>
+</ol>
+</div>
+<div class="sws-slide">
+  <h1>Prédicat imbriqués</h1>
+  <p>On peut imbriquer des prédicats de manière arbitraire:</p>
+  <code>  Q<sub>1</sub> ≡ /child::a[ child::b[ count(descendant::c) &gt; 4 ] ] </code>
+  <p>Quelle différence avec :</p>
+  <code>  Q<sub>2</sub> ≡ /child::a[ count(child::b/descendant::c) &gt; 4 ] </code>
+  <p class="sws-pause">Il suffit de considérer le document :
+    <code> <![CDATA[ <a>
+      <b> <c/> <c/> <c/></b> 
+      <b> <c/> <c/> </b>
+  </a>
+      ]]></code>
+    <tt>Q<sub>1</sub></tt> <s>ne séléctionne rien</s> car il n'y a
+    aucun <tt>b</tt> ayant plus de 4
+    descendants <tt>c</tt>.<br/>     <tt>Q<sub>2</sub></tt> <s>séléctionne</s>
+    la racine car le nombre de descendants <tt>c</tt> de
+    nœuds <tt>b</tt> est plus grand que 4.
+</p>
+</div>
+<div class="sws-slide">
+  <h1><tt>position()</tt> et <tt>last()</tt> </h1>
+  <p>La fonction <tt>position()</tt> renvoie la position du nœud au
+  sein de <a>l'ensemble de résultats en cours de filtrage</a>. Last
+  renvoie le nombre d'éléments dans cet ensemble (ou l'indice du
+  dernier élément). Les indices commencent à 1 :</p>
+  <code><![CDATA[    <a>
+      <b>AA</b>
+      <b>BB</b>
+      <b>CC</b>
+    </a>]]>
+
+    /child::a/child::b[ position() = 2 ]          (renvoie <![CDATA[<b>BB</b>]]>)
+    /child::a/child::b[ position() = last() ]     (renvoie <![CDATA[<b>CC</b>]]>)
+    /child::a/child::b[ position() mod 2 = 1 ]    (renvoie <![CDATA[<b>AA</b>
+                                                           <b>CC</b>]]>)
+</code>
+</div>
+<h1>Axes complexes</h1>
+<div class="sws-slide">
+  <h1>L'axe <tt>attribute::</tt></h1>
+  <p>Permet d'accéder aux attributs d'un élément.<s>Attention</s>, les
+    attributs ne font pas partie des fils ni des descendants!</p>
+    <code><![CDATA[    <a>
+      <b id="a1" v="x" >AA</b>
+      <b id="b2" v="y" >BB</b>
+      <b id="b3" v="z" >CC</b>
+    </a>]]>
+
+    /descendant::b[ attribute::* = "y" ]          (renvoie <![CDATA[<b …>BB</b>]]>)
+    /descendant::b[ attribute::id = "y" ]         (ne renvoie rien)
+</code>
+</div>
+<div class="sws-slide">
+  <h1>Les axes <tt>preceding::</tt> et <tt>following::</tt></h1>
+  <p>L'axe <tt>preceding::</tt> selectionne tous les nœuds arrivant
+    avant le nœud courant et qui ne sont pas des ancetres de ce
+    dernier.</p>
+  <p>L'axe <tt>following::</tt> selectionne tous les nœuds arrivant
+    après le nœud courant et qui ne sont pas des descendants de ce dernier.</p>
+    <code style="background:white;"><![CDATA[    <a>
+      <b > <c/>
+          <d> <e/> </d>
+          <f ><g/></f>
+      </b>
+      <h/>
+      <i/>
+      <j> <k>
+         <l/> <m/> <n/>
+        </k>
+      </j>
+    </a>]]>
+
+    /descendant::m/preceding::* (séléctionne l, i, h, b, c, d, e, f, g)
+    /descendant::d/following::* (sélectionne h, i, j, k, l, m)
+</code>
+</div>
+<div class="sws-slide">
+<h1>Autres opérateurs</h1>
+<p>On peut donner plusieurs prédicats à un chemin :
+<code>
+ <s>/descendant::a [ descendant::b ]</s><a>[ position () &gt; 4 ]</a><span style="color:orange;">[ child::c ]</span>
+</code>
+Sélectionne l'ensemble des nœuds <s>A<sub>1</sub> ayant un
+  tag <tt>a</tt> et ayant un descendant <tt>b</tt></s>. Filtre
+  A<sub>1</sub> pour ne garder que <a>A<sub>2</sub>, l'ensemble des
+  nœuds de A<sub>1</sub> étant en position supérieure à
+  4</a>. <span style="color:orange;">Filtre A<sub>2</sub> pour ne
+  garder que les nœuds ayant un fils <tt>c</tt></span>.
+</p>
+<p>On peut prendre <a>l'union</a> de plusieurs chemins :</p>
+<code>
+    /descendant::a/parent::b | /descendant::c/following-sibling::d
+</code>
+</div>
+<h1>Syntaxe abrégée</h1>
+<div class="sws-slide">
+<h1>Abréviations</h1>
+<p>XPath étant très <a>verbeux</a> il existe une syntaxe abrégée pour
+  les situations les plus courantes :</p>
+<ul>
+  <li> un nom de tag <tt>foo</tt> est l'abréviation
+  de <tt>child::foo</tt>. Exemple : <code> /a/b/c ≡ /child::a/child::b/child::c</code>
+    <br/></li>
+  <li> un <tt>//</tt> est l'abréviation
+  de <tt>/descendant-or-self::node()/</tt>. Exemple :
+    <code> //a ≡ /descendant-or-self::node()/child::a </code>
+    Prend tous les nœuds du document (y compris le
+    nœud fictif <tt>#document</tt> et exécute <tt>child::a</tt> sur
+    cet ensemble.<br/></li>
+  <li> <tt> .. </tt> est un synonyme
+  pour <tt>parent::node()</tt> </li>
+  <li> <tt> @foo </tt> est un synonyme pour <tt>attribute::foo</tt>
+  </li>
+</ul>
+  <p>Exemple :</p>
+  <code>    //book [ year &gt; 2005 ]/title
+  </code>
+
+</div>
+  </body>
+</html>