XPath, XQuery
Dan VODISLAV
Université de Cergy-Pontoise
Plan
• XPath
– Expressions de chemin
– Axes, filtres et prédicats
– Fonctions XPath
• XQuery
– Modèle de données
– Expressions simples et complexes
– Expressions de chemin XPath 2.0
– Construction de noeuds
– Expressions FLOWR
2
XPath
• Langage de sélection d’un ensemble de nœuds dans un document XML
– Utilise des expressions de chemin pour désigner des nœuds dans l’arbre
– Les expressions XPath sont utilisées dans d’autres langages: XSLT, XQuery, …
• Une expression de chemin XPath
– S’évalue en fonction d’un nœud contexte
– Désigne un ou plusieurs chemins dans l’arbre du document à partir du nœud
contexte
– A pour résultat un ensemble de nœuds de l’arbre (qui se situent au bout des
chemins)
• Types de nœuds
– Document, Element, Attribute, Text, Comment, ProcessingInstruction
• XPath offre aussi des expressions littérales (texte, numérique, booléen)
• Ex: 1 + 2
3
Syntaxe XPath
• Expression de chemin: suite d’étapes
[/]étape1/étape2/…/étapen
• Idée: chaque étape successive détermine un ensemble de nœuds à partir du
nœud contexte
– Le reste du chemin utilise chacun des nœuds désignés par l’étape précédente
comme nœud contexte pour la suite de l’évaluation
• Étape = axe::filtre[prédicat1]…[prédicatn]
Exemple: child::B[position()=1] (abréviation: B[1])
• Axe: optionnel (par défaut child)
– Spécifie un ensemble des nœuds par rapport au nœud contexte + un ordre
• Filtre: obligatoire, décrit le sous-ensemble de nœuds de l’axe retenu
• Prédicats: optionnels, décrivent les conditions à satisfaire par les nœuds
– Combinés par l’opérateur "ET" logique
4
Axes XPath
• Douze types d’axes
– child (axe par défaut): enfants directs du nœud contexte
– parent (..): nœud parent
– attribute (@): nœuds attribut du nœud contexte
– descendant (//): nœuds descendants du nœud contexte
– descendant-or-self: descendants, y compris le nœud contexte
– ancestor: nœuds ancêtres du nœud contexte
– ancestor-or-self: ancêtres, y compris le nœud contexte
– following: nœuds suivants dans l’ordre du document
– following-sibling: frères suivants dans l’ordre du document
– preceding: nœuds précédents dans l’ordre du document
– preceding-sibling: frères précédents dans l’ordre du document
– self (.): le nœud contexte lui-même
• Attributs: seul l’axe attribute désigne des nœuds attribut !
5
Filtres et prédicats
• Filtres: deux façons de filtrer les nœuds d’un axe:
– Par leur nom
• Pour les nœuds qui ont un nom (Element, Attribute, ProcessingInstruction)
– Par leur type
• text(), comment(), processing-instruction()
• * : nœuds de type élément ou attribut
• node() : tous les types de nœud
• Prédicat: tests connectés par les opérateurs logiques "ET" et "OU"
– Négation: par la fonction not()
• Test = expression booléenne élémentaire: comparaison, fonction booléenne
– Expression de chemin convertie en booléen
• Ensemble de nœuds: false si l’ensemble est vide, sinon true
• Numérique: false si 0 ou NaN (« not a number »), sinon true
• Chaînes de caractères: false si chaîne vide, sinon true
6
Fonctions XPath
• Pour nœuds
– count(expr): nombre de nœuds dans l’ensemble produit par l’expression
– name(): nom du nœud contexte
• Pour chaînes de caractères
– concat(ch1, ch2, …): concaténation
– contains(ch1, ch2): vérifie si ch1 contient ch2
– substring(ch, pos, l): extrait la sous-chaîne de ch de longueur l, commençant à la
position pos (les positions démarrent à 1)
– string-length(ch): longueur de la chaîne
• Pour booléens
– true(), false(): les valeurs vrai/faux
– not(expr): négation de l’expression logique
• Pour numériques
– sum(expr): somme des valeurs des nœuds produits par l’expression
– avg(expr): moyenne des valeurs des nœuds produits par l’expression
7
Exemples
• D
• D/text()
• descendant::node()
• ..
• following::node()
• preceding-sibling::node()
• //@att1
• /A//D
• /comment()
• ../*
• /A/B//text()[1]
• /A//text()[1]
• //B[@att1="a2"]/D
• /A/B[last()]
• //B[count(D)>1]
• /A/C[not(D)]
• /A[B[D="Texte1"]/@att1]/C/@att2
8
XQuery
• Langage de requêtes pour bases de données XML
– Langage fonctionnel typé, sans effets de bord
• Modèle de données XDM basé sur des séquences ordonnées
– Valeur = séquence ordonnée (liste) d’items
– Item = nœud (tout type DOM) ou valeur atomique
• Document, élément, attribut, texte, … + valeurs atomiques de différents types
– Chaque nœud et chaque valeur atomique a un type (XML Schema)
– Résultat de requête XQuery = valeur = séquence d'items
valeur item
*
item noeud valeur atomique
9
Séquences
• Pas de distinction entre item et séquence de longueur 1
– Ex: 39 = (39)
• Une séquence peut contenir des valeurs hétérogènes
– Ex: (39, "toto", <toto/>)
• Pas de séquences imbriquées
– Ex: (39, (1, 2), "toto", <toto/>) = (39, 1, 2, "toto", <toto/>)
• Une séquence peut être vide
– Ex: ()
• L’ordre est important
– Ex: (1, 2) ≠ (2, 1)
10
Expressions XQuery simples
• Valeurs atomiques littérales (des types simples XML Schema)
Ex: 39, "toto", 3.9, etc.
• Nœuds XML sous forme littérale
Ex: <film annee="2007">
<titre>La môme</titre>
</film>
• Valeurs obtenues par des constructeurs simples
Ex: true(), false(), date("2006-12-08")
• Collections de documents, documents
– document(uri-document) retourne un item de type nœud Document
– collection(uri-collection) retourne une séquence de nœuds Document
Ex: document("[Link]"), collection("cinema/films")
• Séquences construites
Ex: (1, 2, 3, 4, 5), 1 to 5, (1 to 3, 4, 5)
• Variables
– Nom précédé du signe $ ($x, $toto, etc.) + valeur (séquence d'items)
11
Expressions XQuery complexes
• Expressions de chemin (XPath 2.0)
– Toute expression produisant une séquence de nœuds peut être une étape
• Expressions FLWOR avec définition de variables
• Tests (If-Then-Return-Else-Return)
• Fonctions prédéfinies et fonctions utilisateur
• Mélange de littéraux et d'expressions complexes
– Chaque expression doit être placée entre {} pour qu'elle soit évaluée
Ex. <comedies>
{document("[Link]")//film[@genre="comedie"]}
</comedies>
12
Exemple
• Document [Link]
<bib>
<book title="Comprendre XSLT">
<author><la>Amann</la><fi>B.</fi></author>
<author><la>Rigaux</la><fi>P.</fi></author>
<publisher>O’Reilly</publisher>
<price>28.95</price>
</book>
<book year="2001" title="Spatial Databases">
<author><la>Rigaux</la><fi>P.</fi></author>
<author><la>Scholl</la><fi>M.</fi></author>
<author><la>Voisard</la><fi>A.</fi></author>
<publisher>Morgan Kaufmann Publishers</publisher>
<price>35.00</price>
</book>
<book year="2000" title="Data on the Web">
<author><la>Abiteboul</la><fi>S.</fi></author>
<author><la>Buneman</la><fi>P.</fi></author>
<author><la>Suciu</la><fi>D.</fi></author>
<publisher>Morgan Kaufmann Publishers</publisher>
<price>39.95</price>
</book>
</bib>
13
Expressions de chemin
• XPath 2.0
– Modèle XDM, basé sur des séquences, au lieu d'ensembles de nœuds
– Utilisation de tous les types XML Schema
– Étape: toute expression qui retourne une séquence de nœuds
– Nouveaux opérateurs (for, if, some, every), utilisation de variables
• Exemples
– document("[Link]")/bib//book[1]/publisher
• L’éditeur du premier livre
– document("[Link]")//(book union author union publisher)
• tous les livres, auteurs et éditeurs
– document("[Link]")//book/(* except price)
• pour chaque livre tous les éléments fils sauf le prix.
– document("[Link]")//book[every $a in author satisfies
contains($a/la,'a')]
• tous les livres dont tous les auteurs ont la lettre ’a’ dans leur nom de famille
14
Construction de nœuds XML
• Cas 1: nom connu, contenu construit par une expression
– Requête:
<auteurs>
{ document("[Link]")//book[2]/author/la }
</auteurs>
– Résultat:
<auteurs>
<la>Rigaux</la>
<la>Scholl</la>
<la>Voisard</la>
</auteurs>
• La requête fait partie d’un document XML, le résultat est
transformé en fragment XML
15
Construction de nœuds XML (suite)
• Cas 2: le nom et le contenu sont calculés
– Constructeurs d’élément et d’attribut
• element { expr-nom } { expr-contenu }
• attribute { expr-nom } { expr-contenu }
– Requête:
element { document("[Link]")//book[1]/name(@*[1]) } {
attribute { document("[Link]")//book[1]/name(*[3]) }
{ document("[Link]")//book[1]/*[3] }
}
– Résultat:
<title publisher="O’Reilly"/>
16
Expressions FLOWR
• Une expression FLOWR ("flower")
– Itère sur des séquences (for)
– Définit des variables (let)
– Trie les résultats (order by)
– Applique des filtres (where)
– Construit et retourne un résultat (return)
• Itération : for $var in exp
– Affecte la variable $var successivement avec chaque item dans la
séquence retournée par exp
– Exemple:
for $a in document("[Link]")//book[price<30]/author
return $a
– Résultat:
<author><la>Amann</la><fi>B.</fi></author>
<author><la>Rigaux</la><fi>P.</fi></author>
17
Affectation d’ensembles: let
• let $var := exp
– affecte à la variable $var la séquence entière retournée par exp
• Requête:
for $b in document("[Link]")//book[1]
let $al := $b/author
return <livre nb_auteurs="{count($al)}">
{ $al }
</livre>
• Résultat:
<livre nb_auteurs="2">
<author><la>Amann</la><fi>B.</fi></author>
<author><la>Rigaux</la><fi>P.</fi></author>
</livre>
18
Sélection : where
• where exp
– permet de filtrer le résultat par rapport au résultat booléen de l’expression
exp
• Requête:
<livre>
{ for $a in document("[Link]")//book
where $a/author[1]/la = "Abiteboul"
return $a/@title
}
</livre>
• Résultat:
<livre title="Data on the Web"/>
19
Trier : order by
• expr1 order by expr2 (ascending | descending)?
– trier les éléments de la séquence retournée par l’expression expr1 selon
les valeurs retournées par expr2
• Requête:
<livres>
{ for $b in document("[Link]")//book
order by $b/@year
return <livre> { $b/@title, $b/@year } </livre>
}
</livres>
• Résultat:
<livres>
<livre title="Comprendre XSLT"/>
<livre title="Data on the Web" year="2000"/>
<livre title="Spatial Databases" year="2001"/>
</livres>
20
Tests: if-then-else
• Requête:
<livres>
{ for $b in document("[Link]")//book
where $b/author/la = "Rigaux"
return if ($b/@year > 2000)
then <livre recent="true"> {$b/@title}
</livre>
else <livre> {$b/@title} </livre>
}
</livres>
• Résultat:
<livres>
<livre title="Comprendre XSLT"/>
<livre recent="true" title="Spatial Databases"/>
</livres>
21
Quantification
• some $var in expr1 satisfies expr2
– il existe au moins un noeud retourné par l’expression expr1 qui satisfait
l’expression expr2 (quantification existentielle).
• every $var in expr1 satisfies expr2
– tous les nœuds retournés par l’expression expr1 satisfont l’expression expr2
(quantification universelle)
• Requête:
for $a in document("[Link]")//author
where every $b
in document("[Link]")//book[author/la = $a/la]
satisfies $b/publisher="Morgan Kaufmann Publishers"
return string($a/la)
• Résultat:
Scholl, Voisard, Abiteboul, Buneman, Suciu
22