TP XQuery --------- Correction Exercice 1 : ----------------------- Requête 1 : =========== { for $b in doc("biblio.xml")//book where $b/publisher = "Addison-Wesley" and $b/@year > 1991 return {$b/title} } Sélectionne les livres publiés par Addison-Wisley après 1991. Pour chacun d'entre eux, retourne un élément book contenant le titre du livre et possédant un attribut year contenant l'année de publication. Notez l'utilisation du where pour ajouter une contrainte sur les éléments sélectionnés par la boucle for. L'ensemble de ces éléments book est placé dans un élément bib. Requête 2 : =========== { for $b in doc("biblio.xml")//book, $t in $b/title, $a in $b/author return {$t} {$a} } Construit à partir des données bibliographiques une liste d'éléments result contenant les associations titre de livre - auteur (jointure). Ces éléments sont placés au sein d'une balise results. Attention, l'enchaînement de variables avec des virgules dans un for correspond en fait à plusieurs boucles for imbriquées. Requête 3 : =========== { let $a := doc("biblio.xml")//author for $last in distinct-values($a/last), $first in distinct-values($a[last=$last]/first) order by $last, $first return {$last} {$first} { for $b in doc("biblio.xml")/bib/book where some $ba in $b/author satisfies ($ba/last = $last and $ba/first=$first) return $b/title } } Construit pour chaque auteur la liste des livres dont il est un des auteurs. Pour chaque auteur, ces informations sont placées dans une balise result. L'ensemble des ces balises est placé dans un élément results. Une double boucle est nécessaire pour 1/ parcourir la liste des auteurs et 2/ pour chaque auteur, parcourir la liste des livres pour recenser les livres dont il est auteur. Requête 4 : =========== declare function local:books-by-author ($root, $last, $first) { for $b in $root/book where some $ba in $b/author satisfies ($ba/last = $last and $ba/first=$first) return $b/title }; { let $a := doc("biblio.xml")//author for $last in distinct-values($a/last), $first in distinct-values($a[last=$last]/first) order by $last, $first return {$last} {$first} {local:books-by-author(doc("biblio.xml")/bib, $last, $first)} } Construit le même résultat que la requête précédente. La différence réside dans le fait qu'une fonction a été isolée pour exécuter ce qui était dans la requête précédente la boucle intérieure : étant donné un auteur, récupérer l'ensemble des livres dont il est auteur. Requête 5 : =========== { for $b in doc("biblio.xml")//book where count($b/author) > 0 return {$b/title} { for $a in $b/author[position() <= 2] return $a } { if (count($b/author) > 2) then else () } } Pour chaque livre de la bibliographie possédant au moins un auteur, construit un élément book contenant le titre du livre et, s'il y a moins de deux auteurs, la liste des auteurs, sinon, seulement les deux premiers auteurs et un élément vide et-al. L'ensemble est compris dans un élément bib. Requête 6 : =========== declare function local:books-by-author ($root, $last, $first) { for $b in $root/book where some $ba in $b/author satisfies ($ba/last = $last and $ba/first=$first) return $b/title }; { let $a := doc("biblio.xml")//author for $last in distinct-values($a/last), $first in distinct-values($a[last=$last]/first) order by $last, $first return {$last} {$first} {count(local:books-by-author(doc("biblio.xml")/bib,$last, $first))} } Comme la requête 4 en retournant pour chaque auteur, au lieu de la liste des livres qu'il a écrits, le nombre de livres qu'il a écrits. Requête 7 : =========== { for $year in distinct-values(doc("biblio.xml")//book/@year) let $avg := avg(doc("biblio.xml")//book[@year=$year]/price/text()) return } Construit pour chaque année pour laquelle au moins un livre a été publié un élément year possédant un attribut value avec la valeur de l'année concernée et un attribut avgprice contenant le prix moyen des livres publiés cette année-là. L'ensemble est placé dans une balise data.