Réalisation d'une application Web de consultation de données Open Data géolocalisées (recensement des résidences hôtelières).
Suite aux problèmes de performances remontés par certains d'entre-vous avec l'utilisation d'eXist et le jeu de données proposé, les changements suivants sont appliqués :
Pour tordre le cou à quelques conclusions hâtives
Ce document compare les performances de quelques BD (eXist, BaseX, Mysql), sans avoir la prétention de se positionner comme un benchmark complet.
On dispose de données géolocalisées de résidences hôtelières dans le département. On vous demande de réaliser une application Web de consultation de ces données.
Ces données doivent être chargées dans une base de données native XML ; vous utiliserez eXist-db ou BaseX (au choix) ; toutes les requêtes d'extraction des données seront faites en XQuery. L'utilisation d'une base de données relationnelle est proscrite.
Vous pouvez utiliser un serveur Web (Tomcat) supplémentaire entre la base de données et le client. Dans le contexte de ce projet ce n'est pas une obligation, mais peut se révéler pratique notamment pour opérer les transformations XML -> XSLFO avec XSLT puis XSLFO -> PDF avec FOP. L'utilisation de PHP est à proscrire.
eXist est à part entière un serveur d'application, un serveur de base de données XML, et un serveur Web ; il peut sembler inutile d'ajouter en frontal un autre serveur Web.
Notez que c'est une pratique courante pour des raisons de sécurité d'utiliser un serveur Web Apache httpd en frontal afin d'éviter d'exposer directement un serveur d'application ou une BD sur le Web, et qui ont vocation à être déployés derrière la DMZ.
Côté client, vous pouvez utiliser des librairies telles que jQuery ; le recours à JSON est proscrit pour accéder aux données provenant de la base de données. Si vous utilisez GWT, l'utilisation de RPC est proscrit.
Téléchargez le fichier XML et chargez-le dans la BD eXist ou BaseX.
Extrait du fichier :
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <entries xmlns="http://ref.otcnice.com/webservice/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://ref.otcnice.com/webservice/entries.xsd"> <entry> <ID>1021</ID> <name_fr>AC BY MARRIOTT NICE</name_fr> <name_fr_short>AC BY MARRIOTT NICE</name_fr_short> <address> <address_line1>59 Promenade des Anglais</address_line1> <address_line2/> <address_line3/> <zip>06000</zip> <city>NICE</city> </address> <phone>+33 (0)4 93 97 90 90</phone> <fax>+33 (0)4 93 44 06 55</fax> <email>ac.nceac.exec.sec@marriott.com</email> <website>http://www.achotelnice.com</website> <contacts/> <payments> <payment>Visa</payment> <payment>Master Card</payment> <payment>American express</payment> <payment>Diner's club</payment> <payment>Chèques</payment> <payment>Chèques Vacances</payment> <payment>Espèces</payment> <payment>Virements</payment> <payment>Chèques de voyage</payment> <payment>Carte de crédit</payment> </payments> <languages> <language>Anglais</language> <language>Allemand</language> <language>Espagnol</language> <language>Italien</language> <language>Russe</language> <language>Français</language> <language>Néerlandais</language> <language>Arabe</language> <language>Finois</language> <language>Portugais</language> </languages> <labels> <label>Nice Irisée Naturellement</label> </labels> <amenities> <amenity>Accès Internet</amenity> <amenity>Ascenseur</amenity> <amenity>Bar</amenity> <amenity>Bibliothèque</amenity> <amenity>Boutique</amenity> <amenity>Garage privé</amenity> <amenity>Jardin</amenity> <amenity>Equipements pour enfants</amenity> <amenity>Local matériel fermé</amenity> <amenity>Parking privé</amenity> <amenity>Parking public à proximité</amenity> <amenity>Piscine</amenity> <amenity>Restaurant</amenity> <amenity>Salle de sport</amenity> <amenity>Salon</amenity> <amenity>Salon de télévision</amenity> <amenity>Terrasse</amenity> <amenity>Wifi</amenity> <amenity>Accès Internet dans les chambres</amenity> <amenity>Animaux acceptés</amenity> <amenity>Blanchisserie</amenity> <amenity>Bureau de change</amenity> <amenity>Câble, satellite</amenity> <amenity>Climatisation</amenity> <amenity>Coffres clients</amenity> <amenity>Double vitrage</amenity> <amenity>Réservation de prestations</amenity> <amenity>Service en chambre</amenity> <amenity>Téléphone</amenity> <amenity>Télévision</amenity> <amenity>Veilleur de nuit</amenity> <amenity>Voiturier</amenity> <amenity>Accueil enfants</amenity> <amenity>Menu Enfants</amenity> <amenity>Salle de réunion</amenity> <amenity>Chambres vue mer</amenity> <amenity>Chambres communicantes / familiales</amenity> <amenity>Piscine réservée à la clientèle</amenity> <amenity>Equip. personnes handicapées</amenity> <amenity>Toit-terrasse</amenity> </amenities> <profiles> <profile>Handicapé</profile> <profile>Couples</profile> </profiles> <locations> <location>Aéroport</location> <location>Magnan</location> <location>Nice Ouest</location> <location>Gambetta</location> <location>Centre Ville</location> </locations> <categories> <category>Hôtels de tourisme</category> <category>Hôtels pour conférence</category> <category>NN</category> </categories> <stations> <station>Grosso CUM - Promenade</station> <station>Grosso CUM</station> <station>Grosso CUM</station> </stations> <standings_levels> <standings_level>4 étoiles</standings_level> </standings_levels> <options> <option>Accès handicapés</option> </options> <publications> <publication>Meeting guide</publication> <publication>Hébergement</publication> <publication>Nice irisée naturellement</publication> </publications> <common_tags> <common_tag>Rencontres professionnelles</common_tag> </common_tags> <descriptions/> <images> <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191809.jpg</image> <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191814.jpg</image> <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191813.jpg</image> <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191810.jpg</image> <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191811.jpg</image> <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191812.jpg</image> <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191815.jpg</image> </images> <living> <room_count>143</room_count> <room_bath_count>0</room_bath_count> <room_shower_count>143</room_shower_count> <suite_count>22</suite_count> <studio_count>0</studio_count> <apartment_count>0</apartment_count> <room_accessible_count>7</room_accessible_count> <single_count>0</single_count> <double_count>0</double_count> <triple_count>0</triple_count> <twins_count>0</twins_count> <family_count>0</family_count> <area>0</area> <type>94 singles = doubles - 49 twins - 22 triples - 61 vue mer</type> <floor>0</floor> <bedroom_count>0</bedroom_count> <sleeps_count>0</sleeps_count> <furnished_room_count>0</furnished_room_count> </living> <tariffs> <tariff> <name>Chambre simple</name> <unique>0</unique> <min>120</min> <max>500</max> <average>0</average> <fixed>0</fixed> </tariff> <tariff> <name>Chambre double</name> <unique>0</unique> <min>120</min> <max>500</max> <average>0</average> <fixed>0</fixed> </tariff> <tariff> <name>Petit déjeuner</name> <unique>0</unique> <min>0</min> <max>21</max> <average>0</average> <fixed>0</fixed> </tariff> </tariffs> <capacity> <total>0</total> <indoor>0</indoor> <outdoor>0</outdoor> <group>120</group> <room_count>3</room_count> <disabled_count>0</disabled_count> </capacity> <closures/> <spaces/> <opening/> <closing/> <latitude>43.6931</latitude> <longitude>7.25298</longitude> <location_map>G5</location_map> <note>4</note> <niceres_availability>true</niceres_availability> <niceres_id>911</niceres_id> <created>2012-05-03 11:28:24</created> <updated>2013-09-13 15:49:00</updated> </entry> </entries>
C'était comment, avant ?
Réalisation d'une application Web de consultation de mesures géolocalisées de température et d'hygrométrie.
Un fichier W3C XML Schema est également disponible :
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="entries"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="1"> <xsd:element name="entry"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="id" type="xsd:integer"/> <xsd:element name="name_fr" type="xsd:string"/> <xsd:element name="name_fr_short" type="xsd:string"/> <xsd:element name="adress" type="xsd:string"/> <xsd:element name="zip" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="phone" type="xsd:string"/> <xsd:element name="fax" type="xsd:string"/> <xsd:element name="email" type="xsd:string"/> <xsd:element name="website" type="xsd:string"/> <xsd:element name="contacts"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="contact"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="civility" type="xsd:string"/> <xsd:element name="name" type="xsd:string"/> <xsd:element name="title" type="xsd:string"/> <xsd:element name="function" type="xsd:string"/> <xsd:element name="phone" type="xsd:string"/> <xsd:element name="email" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="payments"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="payment" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="labels"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="label" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="amenities"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="amenity" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="profiles"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="profile" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="locations"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="location" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="activities"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="activity" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="categories"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="1"> <xsd:element name="category" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="affiliations"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="affiliation" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="stations"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="station" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="standings_levels"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="standings_level" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="chains"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="chain" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="services"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="service" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="options"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="option" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="FRP_options"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="FRP_option" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="POI_options"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="POI_option" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="publications"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="publication" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="descriptions"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="description"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute name="language" type="xsd:string" use="required"/> <xsd:attribute name="type" type="xsd:string" use="required"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="chains"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="chain" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="images"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="image" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="living"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="room_count" type="xsd:integer"/> <xsd:element name="room_bath_count" type="xsd:integer"/> <xsd:element name="room_shower_count" type="xsd:integer"/> <xsd:element name="room_nosmoking_count" type="xsd:integer"/> <xsd:element name="suite_count" type="xsd:integer"/> <xsd:element name="studio_count" type="xsd:integer"/> <xsd:element name="apartment_count" type="xsd:integer"/> <xsd:element name="area" type="xsd:integer"/> <xsd:element name="type" type="xsd:string"/> <xsd:element name="floor" type="xsd:integer"/> <xsd:element name="bedroom_count" type="xsd:integer"/> <xsd:element name="sleeps_count" type="xsd:integer"/> <xsd:element name="furnished_room_count" type="xsd:integer"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="tariffs"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="tariff"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="unique" type="xsd:integer"/> <xsd:element name="min" type="xsd:integer"/> <xsd:element name="max" type="xsd:integer"/> <xsd:element name="average" type="xsd:integer"/> <xsd:element name="fixed" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="capacity"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="total" type="xsd:integer"/> <xsd:element name="indoor" type="xsd:integer"/> <xsd:element name="group" type="xsd:integer"/> <xsd:element name="room_count" type="xsd:integer"/> <xsd:element name="disabled_count" type="xsd:integer"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="spaces"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="space"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="capacity_theater" type="xsd:integer"/> <xsd:element name="capacity_classroom" type="xsd:integer"/> <xsd:element name="capacity_u" type="xsd:integer"/> <xsd:element name="capacity_cocktail" type="xsd:integer"/> <xsd:element name="capacity_seatedmeal" type="xsd:integer"/> <xsd:element name="ceiling_height" type="xsd:integer"/> <xsd:element name="is_natural_light" type="xsd:integer"/> <xsd:element name="area" type="xsd:integer"/> <xsd:element name="resources"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="resource_path" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="opening"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="opening" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="closing"> <xsd:complexType mixed="true"> <xsd:choice maxOccurs="unbounded" minOccurs="0"> <xsd:element name="closing" type="xsd:string"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="latitude" type="xsd:decimal"/> <xsd:element name="longitude" type="xsd:decimal"/> <xsd:element name="location_map" type="xsd:string"/> <xsd:element name="note" type="xsd:string"/> <xsd:element name="niceres_availability" type="xsd:boolean"/> <xsd:element name="niceres_id" type="xsd:integer"/> <xsd:element name="created" type="xsd:string"/> <xsd:element name="updated" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema>
Faites l'application que vous jugerez intéressante. Elle doit au moins :
Il s'agit du minimum requis, mais vous pouvez trouver vous-mêmes d'autres choses intéressantes à faire avec ces données, comme par exemple chercher un autre dataset et croiser les données avec cet autre jeu de données.
Groupes : 3 individus
Date de début : 15/11/2013
Date de fin : date à définir en janvier 2014
Livrables : un rapport (2 pages) décrivant les aspect techniques de votre projet et les fonctionalités principales, à restituer une semaine avant la démo
Démo : présenter une appli qui marche ; vous devez aussi pouvoir montrer le code de votre appli
Un forum est à votre disposition ; vous pouvez y poser toutes les questions concernant les aspects techniques, organisationels, ou métaphysiques concernant le projet. Il y a aussi un espace pour déclarer vos équipes projets, et un espace pour rechercher un partenaire. Concernant les questions, tout le monde est invité à poster les réponses aux questions posées par les autres (ça donnera des points en plus). Avant de poser une question, n'hésitez pas à consulter le forum au préalable !