+++ /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>XPath (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_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>=, !=, <, <=,
- >, >= </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 op 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 op 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> <</tt>, <tt> <=</tt>, <tt> ></tt> ou <tt>
- >=</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() > 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() >= 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>>=</tt> et on a bien que <tt>2 >= 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::*) >= 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::*) >= 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) > 4 ] ] </code>
- <p>Quelle différence avec :</p>
- <code> Q<sub>2</sub> ≡ /child::a[ count(child::b/descendant::c) > 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 () > 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 > 2005 ]/title
- </code>
-
-</div>
- </body>
-</html>