5. XQuery

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.

Définition XQuery est le "SQL du XML". Il permet d'extraire, filtrer, trier et restructurer des données XML avec une syntaxe expressive basée sur FLWOR.

5.1 Expression FLWOR

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 -->

5.2 Exemples de Base

<!-- 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

5.3 Construction d'Elements XML

<!-- Construction directe -->
<resultat>{$variable}</resultat>

<!-- Construction avec attributs -->
<livre titre="{$b/title}">{$b/author}</livre>

<!-- Construction programmatique -->
element resultat {
  attribute total {$count},
  $content
}

5.4 Fonctions Utiles

FonctionDescriptionExemple
data()Extrait la valeur textuelledata($book/title)
distinct-values()Valeurs uniquesdistinct-values(//publisher)
doc()Charge un documentdoc("books.xml")
concat()Concatenationconcat($first, " ", $last)
count()Nombre d'elementscount(//author)

5.5 Conditions et Boucles

<!-- 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>

5.6 Group By et Agregation

<!-- 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)}"/>

5.7 Jointures entre Documents

XQuery permet de combiner des données de plusieurs fichiers XML avec la fonction doc().

Jointure simple

<!-- 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>

Gestion des jointures sans correspondance

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>
Attention La condition 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).

5.8 Construction XML Avancée

XQuery permet de construire des structures XML complexes avec des statistiques calculées et des boucles imbriquées.

Attributs calculés avec count et distinct-values

<!-- 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>

Boucles imbriquées avec plages numériques

<!-- 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)
  }
Points Examen XQuery

Quiz - Module 5 : XQuery

Testez 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 ?