XQuery est un langage de requête pour interroger et transformer des documents XML. Il combine la puissance de XPath avec des capacités de construction de nouveaux éléments XML et des structures de contrôle avancées.
FLWOR (For, Let, Where, Order by, Return) est la structure de base de XQuery :
for $variable in expression <!-- Iteration -->
let $var := expression <!-- Assignation -->
where condition <!-- Filtrage -->
order by expression <!-- Tri -->
return expression <!-- Resultat -->
<!-- Liste des titres de livres -->
for $book in //book
return $book/title
<!-- Livres avec un seul auteur -->
for $b in //book
where count($b/author) <= 1
return
<Livre>
{$b/title}
<auteur>{$b/author}</auteur>
</Livre>
<!-- Livres tries par annee -->
for $b in //book
order by $b/@year
return $b/title
<!-- Construction directe -->
<resultat>{$variable}</resultat>
<!-- Construction avec attributs -->
<livre titre="{$b/title}">{$b/author}</livre>
<!-- Construction programmatique -->
element resultat {
attribute total {$count},
$content
}
| Fonction | Description | Exemple |
|---|---|---|
data() | Extrait la valeur textuelle | data($book/title) |
distinct-values() | Valeurs uniques | distinct-values(//publisher) |
doc() | Charge un document | doc("books.xml") |
concat() | Concatenation | concat($first, " ", $last) |
count() | Nombre d'elements | count(//author) |
<!-- Condition if/then/else -->
for $b in //book
let $y := $b/@year
return
if ($y > 1995)
then <nouveau date="{$y}"/>
else <ancien date="{$y}"/>
<!-- Boucle avec index -->
for $b at $key in //book
return
<livre>{concat($key, "-", $b/title)}</livre>
<!-- Grouper les auteurs -->
for $a in //author
let $fullname := concat($a/last, " ", $a/first)
group by $fullname
return <auteur>{$fullname}</auteur>
<!-- Statistiques par editeur -->
for $book in //book
let $pub := $book/publisher
group by $pub
return
<editeur nom="{$pub}" count="{count($book)}"/>
XQuery permet de combiner des données de plusieurs fichiers XML avec la fonction doc().
<!-- Joindre livres et informations auteurs -->
for $book in doc("books.xml")//book
for $author in $book/author
let $info := doc("auteurs.xml")//personne[nom = $author/last]
return
<livre titre="{data($book/title)}">
<auteur nom="{concat($author/first, ' ', $author/last)}"
institution="{data($info/institution)}"/>
</livre>
Que faire si aucune donnée n'est trouvée dans le second document ? Utilisez if/then/else :
<!-- Jointure avec gestion des cas sans correspondance -->
for $book in //book
where $book/author
return
<livre titre="{data($book/title)}">
{
for $author in $book/author
let $lastName := $author/last
let $info := doc("auteurs.xml")//personne[nom = $lastName]
return
if ($info) then
<auteur nom="{concat($author/first, ' ', $lastName)}"
institution="{data($info/institution)}"/>
else
<auteur nom="{concat($author/first, ' ', $lastName)}"/>
}
</livre>
if ($info) vérifie si la variable contient un élément. Si le nœud n'existe pas, l'expression retourne une séquence vide (évaluée à false).
XQuery permet de construire des structures XML complexes avec des statistiques calculées et des boucles imbriquées.
<!-- Document avec statistiques globales -->
<books
nbre_editeurs="{count(distinct-values(//publisher))}"
nbre_auteurs="{count(distinct-values(//author/last))}"
>
<titre>Catalogue des publications</titre>
<publications>
{
for $book in //book
return
<publication year="{$book/@year}">
<auteurs>
{
for $author in $book/author
return $author/last
}
</auteurs>
<editeur>{data($book/publisher)}</editeur>
</publication>
}
</publications>
</books>
<!-- Table de multiplication programmatique -->
for $i in (1 to 10)
for $j in (1 to 10)
let $result := $i * $j
return
element resultat {
attribute ligne {$i},
attribute colonne {$j},
concat($i, " x ", $j, " = ", $result)
}
${...} évalue du code XQuery dans un élément XML construit:= est l'opérateur d'assignation (pour let)group by permet l'agrégation comme en SQLdoc() charge un document externe pour les jointuresif ($var) teste si une variable contient des donnéesTestez vos connaissances sur XQuery.
Q1. Que signifie FLWOR ?
Q2. Quel opérateur assigne une variable en XQuery ?
Q3. Comment inclure une variable dans un élément XML construit ?
Q4. Quelle fonction extrait les valeurs uniques ?
Q5. Comment obtenir l'index dans une boucle for ?
Q6. Quelle clause permet de trier les résultats ?