9/4/2002 Conservatoire National des Arts et Métiers Paris 1 1. XML et DTD (4 points) Examen Partiel - Bases de Données - Valeur C Module: Web et Données Durée: 2h30 heures, 9 Avril 2002 Voici une table relationnelle avec des résultats du deuxième tour des éléctions présidentielles de quatre bureaux de vote. Votes dept ville bureau candidat voix 94 Cachan 1 Toto 3398 94 Cachan 1 Dupont 6589 94 Cachan 2 Toto 5645 94 Cachan 2 Dupont 4090 94 L Hay 1 Toto 2067 94 L Hay 1 Dupont 4089 92 Bagneux 1 Toto 4723 92 Bagneux 1 Dupont 5167 Cette table a été traduite en XML (document Imbrique.xml): <?xml version="1.0"?> <Ville nom="cachan" dept="94"> <Candidat nom="toto" voix="3398"/><candidat nom="dupont" voix="6589"/> <Bureau num="2"> <Candidat nom="toto" voix="5645"/><candidat nom="dupont" voix="4090"/> <Ville nom="l Hay" dept="94"> <Candidat nom="toto" voix="2067"/><candidat nom="dupont" voix="4089"/> <Ville nom="bagneux" dept="92"> <Candidat nom="toto" voix="4723"/><candidat nom="dupont" voix="5167"/> 1. Donnez la DTD du document précédent (Imbrique.xml). <!ELEMENT Votes (Ville)*> <!ELEMENT Ville (Bureau)*> <!ATTLIST Ville nom CDATA #REQUIRED dept CDATA #REQUIRED> <!ELEMENT Bureau (Candidat)*> <!ATTLIST Bureau num CDATA #REQUIRED> <!ELEMENT Candidat EMPTY> <!ATTLIST Candidat nom CDATA #REQUIRED voix CDATA #REQUIRED> 2. Exprimez dans la DTD la contrainte que les deux seuls candidats possibles sont Toto et Dupont. <!ATTLIST Candidat nom (Toto Dupont) #REQUIRED>
9/4/2002 Conservatoire National des Arts et Métiers Paris 2 3. Est-ce qu il est possible de spécifier dans la DTD que l ensemble des attributs (dept,ville,bureau,candidat) forme un clé. NON 2. XPath (7 points) 1. Traduisez les requêtes SQL suivantes (sur la table Votes) en requêtes XPath (sur le document Imbrique.xml): (a) select distinct bureau from Votes /Votes/Ville/Bureau[not[@num=preceding::Bureau/@num]/@num (b) select voix from Votes where ville= Cachan and candidat= Dupont /Votes/Ville[@nom= Cachan ]/Bureau/Candidat[@nom= Dupont ]/@voix (c) select ville from Votes where candidat="toto" and voix > 5000 /Votes/Ville[Bureau/Candidat[@nom= Toto and @voix>5000]]/@nom 2. Traduisez les expressions XPath suivantes (sur le document Imbrique.xml) en requêtes SQL (sur la table Votes) : (a) /Votes/Ville/Bureau/Candidat[@voix >../Candidat/@voix]/@nom select A.candidat from Votes A, Votes B where A.voix > B.voix and A.ville=B.ville and A.bureau=B.bureau ou select A.candidat from Votes A where A.voix > any (select B.voix from Votes B where A.ville=B.ville and A.bureau=B.bureau) (b) //Candidat[not(@nom=preceding::Candidat/@nom)]/@nom select distinct candidat from Votes
9/4/2002 Conservatoire National des Arts et Métiers Paris 3 (c) /Votes/Ville[sum(Bureau/Candidat[@nom= Dupont ]/@voix) > 8000]/@nom La fonction XPath sum(p) calcule la somme des valeurs retournées par l expression p. select ville from Votes where candidat= Dupont group by ville having sum(voix) > 8000; 3. XSLT (4 points) Voici un programme XSLT : <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="votes"> <xsl:for-each select="ville/bureau/candidat"> <Vote dept="{../../@dept}" ville="{../../@nom}" bureau="{../@num}" candidat="{@nom}" voix="{@voix}"/> </xsl:for-each> </xsl:template> </xsl:stylesheet> 1. Quelle est le résultat si on applique ce programme au document Imbrique.xml? <Vote dept= 94 ville= Cachan bureau= 1 candidat= Toto voix= 3398 /> <Vote dept= 94 ville= Cachan bureau= 1 candidat= Dupont voix= 6589 /> <Vote dept= 94 ville= Cachan bureau= 2 candidat= Toto voix= 5645 /> <Vote dept= 94 ville= Cachan bureau= 2 candidat= Dupont voix= 4090 /> <Vote dept= 94 ville="l Hay" bureau= 1 candidat= Toto voix= 2067 /> <Vote dept= 94 ville="l Hay" bureau= 1 candidat= Dupont voix= 4089 /> <Vote dept= 92 ville= Bagneux bureau= 1 candidat= Toto voix= 4723 /> <Vote dept= 92 ville= Bagneux bureau= 1 candidat= Dupont voix= 5167 /> 2. Écrivez un programme XSLT qui calcule la somme des voix pour chacun des candidats (à partir du document Imbrique.xml). Le résultat de la transformation donnera le document suivant : <?xml version="1.0"?> <Candidat nom="toto">15833</candidat> <Candidat nom="dupont">19935</candidat> <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="xml" indent="yes"/>
9/4/2002 Conservatoire National des Arts et Métiers Paris 4 <xsl:template match="votes"> <xsl:for-each select="ville/bureau/candidat[not(@nom=preceding::candidat/@nom)]"> <Candidat nom="{@nom}"> <xsl:value-of select="sum(//candidat[@nom=current()/@nom]/@voix)"/> </Candidat> </xsl:for-each> </xsl:template> </xsl:stylesheet> 4. XQuery (5 points) 1. Donnez les résultats des deux requêtes XQuery suivantes sur le document Imbrique.xml: (a) for $a in //Bureau, $x in $a/candidat, $y in $a/candidat[not(@nom = $x/@nom)] if ($x/@voix > $y/@voix) then ($a/../@nom, $a/@num, $x/@nom) else ($a/../@nom, $a/@num, $y/@nom) Pour chaque bureau de vote : le nom de la ville, le numéro du bureau et le nom du candidat gagnant : (Cachan,1,Dupont) (Cachan,1,Dupont) (Cachan,2,Toto) (Cachan,2,Toto) (L Hay,1,Dupont) (L Hay,1,Dupont) (Bagneux,1,Dupont) (Bagneux,1,Dupont) Programme XSLT équivalent: (b) { for $a in distinct(//candidat/@nom) <Client nom={ $a } voix={ sum(//candidat[@nom=$a]/@voix) } /> } Pour chaque candidat: son nom et la somme des voix 2. Donnez la requête XQuery qui retourne le nom du vainqueur des élections. avec deux candidats: let $a in distinct(//candidat/@nom) $b in distinct(//candidat/@nom) where $a <> $b if sum(//candidat[@nom=$a]/@voix) > sum(//candidat[@nom=$b]/@voix) then $a else $b
9/4/2002 Conservatoire National des Arts et Métiers Paris 5 avec plus que deux candidats: for $a in distinct(//candidat/@nom) if every $b in //Candidat[@nom <> $a] satisfies sum(//candidat[@nom=$a]/@voix) < sum(//candidat[@nom=$b/@nom]/@voix) then $a