Introduction 1/35 2/35 Anne-Cécile Caron Master MIAGE - BDA 1er trimestre 2013-2014 Introduction Vous connaissez déjà depuis la licence : I Des langages de définition de schéma (DTD, XML-schema) I Des langages de transformation (XSLT, XSL-FO) Nous avons vu au cours précédent : I le lien entre Bases de données et XML I le choix entre stockage dans un SGBD relationnel étendu, ou dans un SGBD XML natif I l enrichissement de SQL pour pouvoir générer/manipuler du XML. Introduction Modèle de données 3/35 4/35 Introduction Nous allons voir aujourd hui et aux cours suivants : I et XQuery pour interroger des données XML I XUpdate pour modifier des données XML I Les espaces de nom, pour échanger des vocabulaires, des schémas et éviter les conflits de noms Le cours d aujourd hui utilise amplement le livre de Serge Abiteboul et al, Web Data Management http://webdam.inria.fr/jorge/ ainsi que les documents du W3C. Arbre XML I Un document XML est vu comme un arbre de noeuds I on a di érentes sortes de noeuds I Document : le noeud racine du document XML, noté / I Element : les noeuds éléments qui correspondent aux balises I Attribut : un noeud attribut est attaché à un noeud élément I Texte : les feuilles sans balise Il existe aussi des noeuds processing instructions, des noeuds commentaires, et des noeuds pour les espaces de noms, mais ils sont moins fréquents. Pour alléger le cours, on va les ignorer dans un premier temps. On peut représenter un document XML sous sa forme sérialisée, ou sous la forme d un arbre.
Modèle de données Modèle de données 5/35 6/35 Exemple <?xml version="1.0" encoding="utf-8"?> <A> <B att1= 1 > <D>Text 1</D> <D>Text 2</D> </B> <B att1= 2 > <D>Text 3</D> </B> <C att2="a" att3="b"/> </A> Vocabulaire I Ordre du document : pour faire simple, c est l ordre des noeuds lorsqu on considère la représentation sérialisée. I un arbre possède 1 noeud document appelé noeud racine, et ce noeud racine a 1 unique fils élément, appelé élément racine. I Nom et Valeur : 1. un noeud élément a un nom (celui de la balise) mais pas de valeur 2. un noeud texte a une valeur mais pas de nom 3. un noeud attribut a à la fois un nom et une valeur I Content : le contenu d un noeud N dans un arbre XML est le sous-arbre ayant pour racine ce noeud N I Textual content : le contenu textuel d un noeud N est la concaténation des valeurs des noeuds textes descendants de N Modèle de données 2.0 7/35 8/35 Séquence I Un arbre modélise un document XML, une séquence modélise une collection ordonnées d items, un item étant une valeur atomique ou un noeud I Attention : I dans le modèle de 1.0, on manipulait des ensembles de noeuds, donc une collection non-ordonnée et sans doublons. I Dans 2.0 (et donc XQuery) : Le résultat d une requête est une séquence d items (noeuds ou valeurs atomiques), donc une collection ordonnée avec possibilité de doublons. I Pour construire une séquence, on utilise les parenthèses avec la virgule pour concaténation, et l opérateur to pour définir un intervalle. I (10, 1, 2, 3, 4) séquence d entiers I (10, (1, 2), (), (3, 4)) la même séquence I (10, 1 to 4) encore la même séquence I 1.0 recommandation W3C depuis 1999, utilisé pour XSLT 1.0 juste des expressions de chemin. I 2.0 recommandation W3C depuis janvier 2007, fragment de XQuery 1.0 et utilisé dans XSLT 2.0. itération for, conditionnelle if, opérateurs sur les séquences, I Rappelons que dans le modèle de 1.0, le résultat est un ensemble de noeuds, alors que dans le modèle de 2.0, le résultat est une séquence d items. I est un language composable : on peut utiliser une expression comme opérande/paramètre, partout où une séquence est attendue.
2.0 2.0 9/35 10 / 35 Expression de chemin I Une telle expression I s évalue en fonction d un noeud contexte I désigne zéro, un ou plusieurs chemins dans l arbre à partir du noeud contexte I apourrésultatuneséquence(pour2.0) I Une expression de chemin est formée d une succession d étapes séparées par /. I On distingue 2 cas : 1. expression absolue qui commence par /. Lenoeudcontexteestle noeud racine. 2. expression relative qui ne commence pas par /. Lenoeudcontexte n est pas forcément le noeud racine, et dépend du contexte d utilisation de l expression. Etape Une étape s écrit : axe::filtre[predicat1][predicat2] I axe : sens de navigation dans l arbre par rapport au noeud contexte (par défaut, c est child) I filtre : type des noeuds souhaités I prédicats : propriétés que doivent vérifier les noeuds. Les prédicats sont facultatifs, et il existe une syntaxe abrégée pour axe::filtre. Une étape I s évalue en fonction d un noeud contexte I a pour résultat une séquence (pour 2.0) 2.0 2.0 11 / 35 12 / 35 Exemples I /A/B : expression de chemin absolue, qui a pour résultat la séquence des noeuds éléments de nom B, filsdel élémentracinea. I./B/descendant::text() : expression relative, qui a pour résultat la séquence des noeuds textes descendant d un élément B lui même fils du noeud contexte. I /A/B[@att1=2] : expression absolue qui donne la séquence des noeuds éléments de nom B, fils de l élément racine A, dont l attribut att1 vaut 2. Par la suite, nous allons poser des requêtes sur un documents qui contient des informations sur des eaux minérales. Ce documents se divise en 3 parties : 1. une liste des bouteilles d eau stockées. Chaque bouteille possède un code barre et contient une eau. 2. une liste des eaux avec leur nom, source, composition, ph, 3. une liste des produits chimiques (des minéraux) trouvés dans les eaux
2.0 2.0 13 / 35 14 / 35 DTD Exemple Les déclaration des éléments contenant des PCDATA ont été enlevées. <!ELEMENT cave (bouteilles, eaux, produits)> <!ELEMENT bouteilles (bouteille)*> <!ELEMENT bouteille (codebarre,volume)> <!ATTLIST bouteille ref_eau IDREF #IMPLIED> Document Exemple D1 E1 cave <!ELEMENT eaux (eau)*> <!ELEMENT eau (nom_eau, source, composition, ph)> <!ATTLIST eau id ID #REQUIRED> E2 bouteilles E6 eaux <!ELEMENT source (nom_source, dept)> <!ELEMENT composition (taux)*> <!ATTLIST taux ref_produit IDREF #REQUIRED> <!ELEMENT produits (produit)*> <!ELEMENT produit (nom_produit, formule)> <!ATTLIST produit id ID #REQUIRED> A1 ref eau E4 codebarre T1 E3 bouteille E5 volume T2 E7 eau A2 id E8 nom eau T3 2.0 2.0 15 / 35 16 / 35 Evaluation d une expression /descendant::eau/child::nom_eau/child::text() I Au départ, comme c est une expression absolue, le noeud contexte est le noeud document. I Etape 1 : noeuds éléments eau descendant du noeud racine /descendant::eau/child::nom_eau/child::text() I L étape k est interprétée en fonction du résultat de l étape k 1. I Etape 2 : Pour chaque noeud contexte n résultat de l étape 1, trouver les noeuds éléments nom_eau fils de n.
2.0 2.0 17 / 35 18 / 35 /descendant::eau/child::nom_eau/child::text() I Etape 3 : Pour chaque noeud contexte n résultat de l étape 2, trouver les noeuds textes fils de n. I Serialisation du résultat : CristallineCristallineVolvicEvian Les filtres Un filtre permet de sélectionner par un nom ou par un type de noeud. Un filtre peut être : I Un nom d élément ou d attribut I Le caractère * qui sélectionne tous les objets de même nature, uniquement éléments ou attributs : I child::* sélectionne tous les éléments fils du noeud courant, I attribute::* sélectionne tous les attributs du noeud courant. I comment() qui sélectionne les noeuds de type commentaire I text() qui sélectionne les noeuds de type texte I node() qui sélectionne les noeuds de n importe quel type. I processing-instruction() qui sélectionne les noeuds de type P.I. I 2.0 2.0 19 / 35 20 / 35 Les axes I child : sélectionne les noeuds fils du noeud courant, sauf les noeuds attributs. I parent : le noeud père du noeud courant. I descendant : les noeuds descendants du noeud courant, sauf les noeuds attributs I ancestor : les éléments ancêtres I self : le noeud courant lui-même I ancestor-or-self, descendant-or-self I following-sibling (preceding-sibling) : les noeuds frères droits (les noeuds frères gauches) I following (preceding) : les noeuds non attributs dont la balise ouvrante (fermante) apparaît après (avant) dans le document, à l exception des noeuds descendants et ancêtres. I attribute : les noeuds attributs de l élément courant I namespace : les espaces de noms child et parent I L étape child::nom_eau donne les noeuds éléments nom_eau fils des noeuds de l étape précédente. Le filtre est un nom d élément. I child::* donne tous les noeuds éléments fils du noeud contexte, peu importe leur nom. I child::text() donne les noeuds textes fils des noeuds de l étape précédente. Le filtre est un type de noeuds. I child étant l axe par défaut, on peut l omettre : /descendant::eau/nom_eau/text() I parent::node() peut être abrégé en.. Par exemple, /descendant::text()/.. donne tous les noeuds parents des noeuds textes. I Les noeuds attributs ont un parent, pourtant les noeuds attributs ne font pas partie des fils de leur parent. /descendant::eau/attribute::id/parent::* Cette requête donne tous les éléments eau ayant un attribut id et descendants de la racine.
2.0 2.0 21 / 35 22 / 35 attribute I Cet axe permet de sélectionner les noeuds attributs du noeud contexte I Le filtre est soit un nom d attribut, soit * pour n importe quel nom I attribute::nom est équivalent à @nom, attribute::* est équivalent à @* I Comme on l a vu pour child et parent, on peut appliquer un axe sur un attribut, mais les attributs ne sont pas sélectionnés par les axes di érents de attribute. Par exemple: //produit/@id/following-sibling::node() sélectionne (entre autres) un noeud élément nom_produit, mais //nom_produit/preceding-sibling::node() ne sélectionne pas de noeud attribut. descendant et ancestor I L axe descendant donne les noeuds descendants du noeud courant, sauf les noeuds attributs. I Le noeud contexte ne fait pas partie du résultat de descendant, mais il est inclus dans descendant-or-self. I L axe ancestor donne les noeuds ancêtres, y compris la racine du document. I Le noeud contexte ne fait pas partie du résultat de ancestor, mais il est inclus dans ancestor-or-self. I /descendant-or-self::node()/ peut être remplacé par // 2.0 2.0 23 / 35 24 / 35 following-sibling et preceding-sibling //eaux/eau/preceding-sibling::node() following et preceding /cave/eaux/following::* Donne les éléments (filtre *) qui sont après eaux dans l ordre du document. Tous les noeuds (sur l exemple noeuds éléments et commentaire) frères gauches d un élément eau. En remplaçant le filtre * par node(), onauralesnoeudséléments,textes, commentaires, mais pas les noeuds attributs.
2.0 2.0 25 / 35 26 / 35 Les prédicats I Un prédicat est une expression qui peut être évaluée à vrai ou faux I En fait, n importe quelle expression convient! I Voici comment convertir une expression en une valeur booléenne : I Une séquence vide vaut faux I Une séquence dont le premier item est un noeud vaut vrai I Un singleton qui contient une valeur booléenne vaut cette valeur. I Un singleton qui contient une chaîne de caractère vaut vrai ssi cette chaîne est non vide I Un singleton qui contient un nombre vaut vrai pour un nombre di érent de 0, faux sinon. Les prédicats (suite) I Dans une expression, axe::filtre donne comme résultat une séquence de noeuds. Le prédicat qui suit s applique sur chacun des noeuds de la séquence. Pour chaque noeud, si le prédicat vaut vrai, le noeud est conservé, sinon le noeud est rejeté. I On peut enchaîner des prédicats en les juxtaposant : [p1][pk]. I Un prédicat peut être composé d autres prédicats grâce aux opérateurs and et or. I Un prédicat peut être une égalité ou une inégalité définie à l aide des opérateurs!= < > <= >= I Les prédicats peuvent utiliser une fonction portant sur les noeuds. I Attention à la comparaison de 2 séquences : quantification existentielle (1 2) = (2 3) vaut vrai, donc l égalité n est pas transitive!! 2.0 2.0 27 / 35 28 / 35 Quelques fonctions I id("valeur") : retourne l élément dont l identifiant vaut "valeur". Onpeutpasseruneséquencedevaleursenparamètre,le résultat est la séquence des éléments correspondants, sans doublons. il faut qu il y ait une déclaration d attribut de type ID dans la DTD pour que ça fonctionne. I position() : retourne la position du noeud dans la séquence. La première position vaut 1, la dernière vaut last(). I count(séquence-de-noeuds) Retourne le nombre de noeuds présents dans la séquence I not(predicat) renvoie vrai ssi predicat a la valeur faux. I manipulation de chaînes de caractères : contains, concat I fonctions numériques : somme, valeur arrondie, Exemples de requêtes avec prédicats //nom_eau[text()="volvic"]/.. -- 1 noeud élément <eau id="e3"> <nom_eau>volvic</nom_eau> <source> </source> <composition> </composition> <ph>7</ph> </eau> /cave//*[@id="e2"]/following-sibling::* -- 2 noeuds éléments : <eau id="e3"> </eau> <eau id="e4"> </eau>
2.0 2.0 29 / 35 30 / 35 Exemples avec des fonctions //produit[position()=2] -- le deuxième produit dans l ordre du document /cave/*/*[position()=1] -- le premier fils de chaque noeud résultat de l étape 2, donc 3 noeuds : <bouteille ref_eau="e1"></bouteille> <eau id="e1"></eau> <produit id="cal"></produit> Résumé des abréviations possibles I child:: peut être omis I attribute:: peut être remplacé par @ I /descendant-or-self::node()/ peut être remplacé par // I self::node() peut être remplacé par un point. I parent::node() peut être remplacé par.. I [position()=x] peut s écrire [x] //produit[formule/text()="mg+"][position()=2] -- pas de résultat car //produit[formule/text()="mg+"] ramène un singleton count(/cave/eaux/following::*) -- 1 item valeur 16 /id(//bouteille[position()=2]/@ref_eau)/composition -- la fonction id() s applique à l identifiant de l eau de la seconde -- bouteille et a pour résultat le noeud référencé (donc un élément eau) -- On obtient ici la composition de de cette eau 2.0 2.0 31 / 35 32 / 35 Opérateurs ensemblistes sur les séquences opérateurs ensemblistes union (noté aussi ), intersect, except //bouteille union //eau //(bouteille union eau) //bouteille union //bouteille -- identique à //bouteille, donc pas de doublon Composabilité : (exp1 ope exp2) étant une expression, elle peut être utilisée comme étape d une expression de chemin : //(bouteille union eau)/* -- tous les fils (non attributs) des éléments bouteille et eau Instruction conditionnelle if ( Expression ) then Expression else Expression Le else est obligatoire, car une expression a toujours une valeur de type Séquence (composabilité). if (count(//bouteille)>2) then //codebarre else //volume -- renvoie 5 éléments codebarre //bouteille/(if (./volume>50) then./codebarre else./volume) -- renvoie 5 items : <codebarre>3274080005003</codebarre> <volume>50</volume> <codebarre>3546543211234</codebarre> <volume>50</volume> <codebarre>3421234567894</codebarre> -- le else est obligatoire mais on peut renvoyer la séquence vide () //bouteille/(if (./volume>50) then./codebarre else ()) -- renvoie 3 items
2.0 2.0 33 / 35 34 / 35 Expression quantifiée C est une expression booléenne, avec des variables toutes quantifiées existentiellement (some) ou universellement (every). some $var_1 in Expression_1,, $var_k in Expression_k satisfies Expr every $var_1 in Expression_1,, $var_k in Expression_k satisfies Expr La boucle For for $var_1 in Expression_1,, $var_k in Expression_k return Expression Exemple : for $b in //bouteille, $e in id($b/attribute::ref_eau) return $e Par exemple some $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4 -- vaut vrai every $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4 -- vaut faux some $x in //eau[1]/composition/taux/@ref_produit satisfies $x = "cal" -- vaut vrai car il y a du calcium dans la première eau Conclusion 35 / 35 Conclusion I 2.0 est un peu plus expressif que 1.0, même si la base est formée des expressions de chemins présentes dans 1.0 I Une expression renvoie une séquence d items, sur lesquels on peut à nouveau appliquer une expression : langage composable. I Avec, on sélectionne des noeuds. Pour structurer le résultat, utiliser un langage comme XQuery 1.0, qui est un sur-ensemble de 2.0