Langages centrés données 1/10/2015 M2 Fiil



Documents pareils
Module BDWEB. Maîtrise d informatique Cours 9 - Xquery. Anne Doucet. anne.doucet@lip6.fr

Bases de données documentaires et distribuées Cours NFE04

BD et XML : Exercices

1 Introduction et installation

OCL - Object Constraint Language

Bases de données - Modèle relationnel

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Module Criteo Tags et Flux pour Magento

TP1 : Initiation à l algorithmique (1 séance)

Algorithmique et Programmation, IMA

Introduction à Eclipse

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

1. Installation du Module

XML par la pratique Bases indispensables, concepts et cas pratiques (3ième édition)

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

Générer du code à partir d une description de haut niveau

Thierry BOULANGER. par la pratique. Bases indispensables Concepts et cas pratiques XML. 3 ième édition. Nouvelle édition

Introduction à ElasticSearch

Sage 100 CRM Guide de l Import Plus avec Talend Version 8. Mise à jour : 2015 version 8

Manuel d utilisation 26 juin Tâche à effectuer : écrire un algorithme 2

Les arbres binaires de recherche

TelSurvey Système CATI pour LimeSurvey 11 novembre Manuel administrateur

Manuel de l administrateur

Université de Bangui. Modélisons en UML

Guide de démarrage Tradedoubler. Manuel éditeur / affilié

Introduction aux outils BI de SQL Server Fouille de données avec SQL Server Analysis Services (SSAS)

Chapitre VI- La validation de la composition.

BIRT (Business Intelligence and Reporting Tools)

Gestion des références bibliographiques. Comment simplifier la gestion des références bibliographiques?

Les logiciels gratuits en ligne

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

EXCEL TUTORIEL 2012/2013

Cours 1 : La compilation

LES OUTILS D ALIMENTATION DU REFERENTIEL DE DB-MAIN

IMPORTATION ARTICLES DANS LA BASE DE DONNEES

TP1 : Initiation à Java et Eclipse

Calculabilité Cours 3 : Problèmes non-calculables.

1. Introduction / Identification

Chapitre 10 Arithmétique réelle

OpenText StreamServe Cours Customer Communication Management L essentiel

1. Introduction Création d'une requête...2

Cours d initiation à la programmation en C++ Johann Cuenin

TP1 : Initiation à Java et Eclipse

1 - Connexion au service de gestion des demandes informatiques du lycée

< Atelier 1 /> Démarrer une application web

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Gestion Électronique de Documents et XML. Master 2 TSM

Approche Contract First

Construire des plug-ins pour SAS Management Console SAS 9.1

Table des Matières. Pages 3-4. A propos d emblue. Page 5. L environnement emblue. Création d une campagne d marketing. Pages 6-15.

Faculté Polytechnique de Mons. Le processus d Extraction, Transformation et Load (ETL) dans des entrepôts de données XML

Ingénierie Dirigée par les Modèles. Editeurs de modèles. (Eclipse Modeling Tools) Jean-Philippe Babau

TP base de données SQLite. 1 Différents choix possibles et choix de SQLite : 2 Définir une base de donnée avec SQLite Manager

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

INSTALLATION ET CONFIGURATION DE OPENLDAP

Manuel d installation de Business Objects Web Intelligence Rich Client.

STRUCTURE DE L ORDINATEUR

GEST_INSTANCES APPLICATION DE GESTION DES INSTANCES ET REUNIONS EN EPLE ETABLISSEMENT PUBLIC LOCAL D ENSEIGNEMENT

Accès à l'information XML par des requêtes XQuery au travers de son XSchema

Procédures Stockées WAVESOFT ws_sp_getidtable Exemple : ws_sp_getnextsouche Exemple :... 12

LES TOUT PREMIERS PAS

XML, PMML, SOAP. Rapport. EPITA SCIA Promo janvier Julien Lemoine Alexandre Thibault Nicolas Wiest-Million

Mise en place du Module Magento ShoppingFlux

Gestion de références bibliographiques

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

introduction Chapitre 5 Récursivité Exemples mathématiques Fonction factorielle ø est un arbre (vide) Images récursives

Trier les ventes (sales order) avec Vtiger CRM

Reporting Services - Administration

Excel avancé. Frédéric Gava (MCF)

Poker. A rendre pour le 25 avril

Débuter avec Excel. Excel

! Text Encoding Initiative

Rappels sur les suites - Algorithme

chapitre 4 Nombres de Catalan

Réglages du portail de P&WC

données en connaissance et en actions?

Algorithmique I. Algorithmique I p.1/??

mon site web via WordPress

Annexe C Spécification pour les fichiers importés en format XML

SQL Parser XML Xquery : Approche de détection des injections SQL

Probabilités sur un univers fini

NoSQL. Introduction 1/23. I NoSQL : Not Only SQL, ce n est pas du relationnel, et le contexte. I table d associations - Map - de couples (clef,valeur)

Analyse de sécurité de logiciels système par typage statique

Formula Negator, Outil de négation de formule.

Mesurer les performances (CPU) sous Linux

TP 1. Prise en main du langage Python

BASE DE DONNÉES XML NATIVE

Big Data. Cyril Amsellem Consultant avant-vente. 16 juin Talend

Formation. Module WEB 4.1. Support de cours

Langage SQL : créer et interroger une base

CREATION D UNE EVALUATION AVEC JADE par Patrick RUER (

EXA1415 : Annotations

UML et les Bases de Données

Transcription:

Langages centrés données 1/10/2015 M2 Fiil Exercice 1 TD n o 2 Pour cet exercice, récupérer les fichier ApplyXPath.class, movies.xml et movies.dtd sur la page du cours (bouton droit, enregistrer sous). Pour évaluer une expression XPath sur un fichier, on peut utiliser la classe java ApplyXPath présent dans le répertoire de travail : java ApplyXPath fichier.xml 'expression XPath' où expression XPath est votre requête XPath (entourée de guillemets simples). Donner des expressions XPath correspondant aux requêtes suivantes (certaines questions, ou sont très difficiles) : évaluation Il y a pas mal de subtilités dans l évaluation d XPath, détaillée au fur et à mesure de l exercice. Il faut garder en tête le schéma d évaluation suivant (expliqué en cours). Une requête /s 1 /s 2 //s n est appliquée à un noeud fictif, situé au dessus de la racine du document. À chaque pas, on prend l ensemble de nœuds du pas précédant, on lui applique le pas s i ce qui donne un ensemble de nœuds résultants, puis on concatène ces ensembles de nœuds intermédiaires et on les passe comme argument au pas s i+1. Considérons le document (les indices ici ne font pas partie du document mais sont juste là pour rendre les exemples plus parlants) : <a 1 > <b 2 > <c 3 /> <d 4 /> </b> <b 5 > <c 6 /> <e 7 /> </b> <f 8 > <c 9 /> <e 10 /> </b> </a> et le chemin /*/b/c. Ce chemin est en syntaxe abrégée. En syntaxe étendue, il s écrit : /child::*/child::b/child::c. L évaluation à lieu de la manière suivante. On est au dessus de la racine (sur le nœud fictif). On évalue child::*, ce qui renvoie un ensemble de nœuds { a 1 }. Sur cet ensemble de nœuds on applique child::b, ce qui renvoie le résultat intermédiaire : { b 2, b 5 }. Pour chacun des nœuds du résultat intermédiaire, on applique child::c, ce qui donne { c 3 } (pour le premier) et { c 6 } (pour le second), puis on concatène les résultats intermédiaires et on a le résultat final { c 3, c 6 } Syntaxe abrégée vs. Syntaxe étendue la vraie syntaxe (syntaxe concrète) pour XPath, est donnée par la grammaire : 1

P ::= /s/... /s chemin absolu s/... /s chemin relatif s ::= axe::test pas simple axe::test[φ]... [φ] pas avec prédicats axe ::= self child parent descendant ancestor following-sibling preceding-sibling descendant-or-self... test ::= * n importe quel élément tag un tag particulier text() un noeud texte node() n importe quel noeud φ ::= φ or φ φ and φ not(φ) connecteurs φ op φ opération f(φ) appel de fonction P chemin "chaine" 42 literaux En syntaxe abrégée, on peut écrire.../x/...pour signifier.../child::x/...et...//...pour signifier.../descendant-or-self::node()/...ainsi, // signifie chercher tous les descendants du noeuds courant vérifiant la suite du chemin. Il y a cependant de subtiles différences entre descendant:: et // (cf. Exo 3). comparaison Les comparaisons sont existentielles. Supposons qu on écrive //a[ φ 1 = φ 2 ] φ 1 et φ 2 peuvent par exemple être des expressions XPath et donc renvoyer chacune des séquences de noeuds : l 1 {t 1 ;... ; t n } et l 2 {s 1 ;... ; s m }. La comparaison vaudra vrai (et donc le prédicat sera vérifié) ssi : i 1..n, j 1..m. t.q. t i = s j (et pareil pour!=, <=,...) En particulier, [ not( φ 1 = φ 2 )] et [ φ 1!= φ 2 ] ne signifient pas du tout la même chose. Dans le premier on souhaite qu aucun élément de gauche ne soit égal à un élément de droite, alors que dans le deuxième on demande qu il existe un élément à gauche différent d un élément à droite. 1. Renvoyer tout le document /*, /movies. Ici les deux marchent, on applique bêtement l algo, on est au dessus de la racine et on fait un pas pour selectionner le nœud racine. 2. Renvoyer tous les éléments title du document //title, /descendant::title, /movies/movie/title. Les deux premiers selectionnent tous les title du document (quel que soit le document), la troisième est spécifique au type de document qu on considère (mais les 3 seraient acceptables comme réponse) 3. Renvoyer tous les prénoms de réalisateur (avec doublons) 2

Ici, avec doublons veut juste dire que l on ne cherche pas à éliminer les multiples occurences d un prénom si elles existent. Il faut faire attention, il y a des firstname à la fois sous director et actor (cf. la DTD de l exo 1). Il faut donc que director apparaîsse dans le chemin. Réponses possibles ://director//firstname, /descendant::director/descendant::firstname, /movies/movie/directors/name/firstname, (et autres variations similaires) 4. Renvoyer le titre de tous les films dont l année de sortie est inférieure strictement à 1980 Ici on utilise un prédicat : //movie[ year < 1980 ]/title (on peut aussi donner explicitement /movies/ au lieu du // initial). Ici il faut bien faire attention à ce qui se passe, car beaucoup de choses sont cachées. On descend sur tous les nœuds movie. Pour chacun d eux, on teste year < 1980, i.e. on applique le chemin relatif year au noeud movie, donc on récupère une liste de résultat contenant un unique nœud year, que l on compare à une liste contenant un unique entier, 1980. La spéc. nous dit que pour comparer un nœud et un entier, on caste d abord le nœud en chaîne de caractères, puis la chaîne en entier et enfin on compare les deux entiers. Donc ici si on a dans le document <year>2000</year>, le moteur XPath fait la conversion pour obtenir la chaîne "2000" puis la conversion pour obtenir l entier 2000 qu il compare à 1980. Une fois que l on a gardé les nœuds movie qui vérifient ce prédicat, on prend pour chacun d eux leur fils title. 5. Renvoyer le titre de tous les films qui ont au moins un titre alternatif La valeur booléene d un chemin (dans un prédicat) est vrai ssi le chemin renvoie au moins un résultat. On peut donc écrire la requête comme ceci : //movie[ alternate_titles/* ]/title Ici le sous-chemin relatif alternate_titles/* renvoie tous les fils (quel que soit leur tag) du nœud alternate_title se trouvant sous le nœud courrant movie. Si cet ensemble de fils est non-vide, alors le prédicat vaut vrai et on garde le movie courant dans la liste des résutlats intermédiaires. On peut ensuite déscendre facilement sur title. Une autre manière de faire est d utiliser la fonction count( ) même si c est un peu moins efficace en pratique : //movie[ count(alternate_titles/*) >= 1 ]/title 6. Renvoyer le titre de tous les films qui ont au moins un titre alternatif en français //movie[alternate_title/atitle/@country = "fr" ]/title ou en syntaxe concrète : /descendant::movie[ child::alternate_title/child::atitle/attribute::country = "fr" ]/child::title 7. Renvoyer le titre de tous les films dont le réalisateur est Quentin Tarantino //movie[ directors/director/name[ firstname = "Quentin" and lastname = "Tarantino"] ]/title On remarque la possibilité de faire des prédicats imbriqués. 8. Renvoyer le titre des films dont la description contient le mot "robot" 3

On utilise la fonction contains(, ) : //movie[ contains( summary, "robot")/title] 9. Renvoyer les films (élément movie) où Clint Eastwood est acteur et réalisateur Là encore, pas trop de difficulté : //movie[ actor[ name[ firstname = "Clint" and lastname = "Eastwood"]] and directors/director[ name[ firstname = "Clint" and lastname = "Eastwood"]]] 10. Comme précédemment mais renvoyer le rôle de Clint Eastwood //movie[directors/director[ name[ firstname = "Clint" and lastname = "Eastwood"]]]/actor[ name[ firstname = "Clint" and lastname = "Eastwood"]]/role 11. Renvoyer le titre des films dont la durée est supérieure à la moyenne Très subtile Une réponse naturelle est de faire : //movie[ runtime > sum(//runtime) div count(//runtime) ]/title Comme il y a autant de runtime que de movie (d après la DTD) l expression du dessus semble correcte. Malhreusement c est sans compter la perfidie des conversions de types en XPath. Pour faire des comparaisons numériques (à droite du > il y a div, count etc, donc le moteur comprend que la comparaison se fait sur des nombres et pas des chaînes de caractères), XPath prend la valeur chaîne d un élément puis la caste en nombre (par exemple la chaîne "442" devient l entier 442). Il se trouve qu il y a dans le document d origine des <runtime/>, donc sans contenu (ou avec la chaîne vide comme contenu). Considérons un document où on aurait : <movies> <movie> <runtime>5</runtime> </movie> <movie> <runtime/> </movie> <movie> <runtime>10</runtime> </movie> </movie> (on fait abstraction des autres tags). L expression //runtime renvoie la séquence d élements : <runtime>5</runtime>, <runtime/>, <runtime>10</runtime>. En lisant la doc de sum() on voit qu elle prend une séquence d objets en arguments et, si ce ne sont pas des nombres, les caste d abord en chaîne de caractères puis en nombres. Le cast en chaîne donne : "5", "", "10", puis le cast en nombres donne : 5, NaN, 10 (car la chaîne vide n est pas une représentation valide pour un nombre, donc on a le nombre spécial Not a number aussi renvoyé dans des cas spéciaux comme sqrt(-1)). La somme de tout celà donne donc NaN, qui, divisé par un entier reste NaN et rend la comparaison fausse pour tous les nœuds, donc aucun movie n est séléctionné (car sum(//runtime) div count(//runtime) est une valeur globale, la moyenne des durées. On repart de la racine pour la calculer donc c est la même pour tous les éléments). La bonne réponse est : //movie[ runtime/text() > sum(//runtime/text()) div count(//runtime/text()) ]/title En effet ici, la liste intermédiaire de //runtime est toujours <runtime>5</runtime>, <runtime/>, <runtime>10</runtime> mais on applique le pas./text() à chacun des éléments, qui renvoie entre autre la séquence vide pour l élément du milieu. On se retrouve donc uniquement avec "5", "10" et là la sum va bien fonctionner (pas de NaN). 12. Renvoyer le titre des films dont l année de sortie est bissextile 4

Juste pour écrire des and et or //movie[ (year mod 4 == 0) and (year mod 100!=0 or year mod 400 == 0) ]/title 13. Renvoyer le titre des films pour lesquels le titre français et le titre original sont identiques //movie[ title = alternate_titles/atitle[ @country = "fr" ] ]/title la partie gauche de l égalité selectionne le titre du film, la partie droite tous les titres alternatifs dont l attribut country vaut "fr" 14. Renvoyer le titre des films dont le titre est contenu dans la description //movie[ contains(description, title) ]/title 15. Renvoyer le titre des films pour lesquels l un (au moins) des roles des acteurs apparait dans le titre du film. On se souvient que les filtres sont des conditions existentielles. il faut aussi faire attention, on ne peut pas faire contains(title, actor/role) car le deuxième élément de contains doit être une chaîne et pas une liste de chaînes. On descend donc jusqu à actor. De là on peut écrire une expression qui renvoie un titre (parent::*/title et une expression qui renvoie 1 role (role) //movie/actor[ contains( parent::*/title, role) ]/parent::*/title 16. Renvoyer le titre des films pour lesquels deux acteurs ont le même nom de famille Ici la difficulté est de parler de deux acteurs distincts. Si on fait naivement : //movie[ actor/name/lastname = actor/name/lastname]/title Ça ne marche évidemment pas bien car les deux chemins peuvent selectionner le même nœud et donc le prédicat est toujours vrai. On va plutot descendre sur un nœud actor puis le comparer avec un de ses frères : //movie/actor[ name/lastname = following-sibling::actor/name/lastname ] /parent::*/title Attention, entre les crochets, le nœud courant est un actor, donc en utilisant name on descend d un cran, mais en utilisant following-sibling on reste au même niveau. Comme on est descendu jusque sur actor, il faut remonter d un cran pour pouvoir réaccéder au title. Variante sans parent mais avec un prédicat imbriqué : //movie[ actor[ name/lastname = following-sibling::actor/name/lastname]]/title 17. Renvoyer les noms de famille des réalisateurs qui n apparaissent qu une fois dans le document (en tant que réalisateur) On utilise la même technique que pour la question précédente, mais on étend à tout l arbre. Les réalisteurs uniques sont ceux pour les quel, il n est pas vrai, qu il existe un élément, avant dans le document ou après dans le document qui est égal. On utilise l axe following (resp. preceding), qui renvoie tous les noeuds qui ont un pré-ordre plus grand (resp. plus petit) et qui ne sont pas des descendants. Moralement si <x> </x> est un nœud du document, ses following sont tous les éléments dont le tag ouvrant <y> se trouve après le tag fermant </x>. Les nœudspreceding sont les nœuds<z> </z> tel que </z> arrive avant <x> dans l ordre du document. //director [ not (name/lastname = following::director/name/lastname) and not ( name/lastname = preceding::director/name/lastname) ]/name/lastname 5

Encore une fois on note bien que not( x = y ) n est pas la même chose que x!= y. 18. Renvoyer le troisième film (dans l ordre du document) dans lequel apparait Morgan Freeman (Voir aussi Exo 3) Il vaut mieux utiliser /descendant::movie plutot que //movie /descendant::movie[ actor[lastname="freeman" and firstname="morgan"]][position() = 3] Il est très important ici de mettre les prédicats en séquence et de ne pas utiliser un and. En effet dans la requête ci-dessus, on sélectionne d abord tous les films (i), puis on filtre ceux dont l un des acteurs est Morgan Freeman (ii), et seulement ensuite on récupère le 3ème élément de cette liste (iii). Si on avait fait : /descendant::movie[ actor[lastname="freeman" and firstname="morgan"] and position() = 3] Alors on sélectionne tous les films (i), puis on garde ceux pour qui l un des acteurs est Morgan Freeman ET la position est 3. Cette requête ne marchera évidemment que si le 3ème film du document a Morgan Freeman comme acteur. 19. Renvoyer tous les films dont l ordre d apparition dans le document est supérieur à la durée Requête complètement artificielle pour utiliser position() : //movie[ runtime/text() < position() ] 20. Renvoyer la liste de tous les prénoms de réalisateurs, sans doublons On réutilise les même techniques qu à la question 17 : On affiche tous les prénoms de réalisateur sauf ceux pour lesquels il existe, plus loin dans le document un réalisateur de même prénom. //director/name [ not(firstname = following::director/name/firstname) ]/firstname Si un prénom apparait plusieurs fois dans le document, seule la dernière occurence sera affichée. Si on remplace following par preceding seule la première occurence sera affichée. 21. Renvoyer les réalisateurs (élément director) qui jouent dans leur film A strictement parler impossible à faire en XPath. Le mieux qu on puisse faire c est : //director [ name = parent::*/parent::*/actor/name ] On descend sur director et on teste que la valeur chaine de l élément name est égale à celle d un acteur (on remonte sur directors puis movie pour pouvoir redescendre sur actor). Malheureusement name contient deux sous éléments donc le test d égalité concatène leurs valeurs chaînes. Ainsi : <movie> <directors> <director> <name> <firstname>toto</firstname><lastname>titi</lastname> </name> <director> </directors> <actor> 6

<name> <firstname>to</firstname><lastname>totiti</lastname> </name> </actor> sera selectionné. On voudrait tester que sous deux nœuds(director and actor) les firstname sont égaux et les lastname sont égaux. Ce n est pas une requête possible en XPath. Exercice 2 En repartant de l exercice du TP1 (interface graphique pour une base de données de films) dont un corrigé est disponible sur la page du cours, écrire une classe XMLModel qui implémente l interface IModel. Cette classe doit charger un fichier XML (au lieu d un fichier CSV) tel que le fichier movies.xml donné à l exercice 1. Le document XML sera représenté par un objet de type Document. Les requêtes seront des requêtes XPath. Les packages suivants sont nécessaires 1 : //Factory pour construire des éléments XML import javax.xml.parsers.documentbuilder; import javax.xml.parsers.documentbuilderfactory; //Les types de noeuds qu'on utilise import org.w3c.dom.document; import org.w3c.dom.node; //Requêtes XPath import javax.xml.xpath.xpath; import javax.xml.xpath.xpathfactory; 1. la liste n est pas exhaustive, le but est de l exercice est aussi de lire la documentation et de comprendre quelles classes sont utiles. 7