dans des entrepôts de données XML - CoDE - Université Libre de ...
dans des entrepôts de données XML - CoDE - Université Libre de ...
dans des entrepôts de données XML - CoDE - Université Libre de ...
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Faculté Polytechnique <strong>de</strong> Mons<br />
Johnny TSHEKE SHELE<br />
Le processus d’Extraction,<br />
Transformation et Load (ETL)<br />
<strong>dans</strong> <strong><strong>de</strong>s</strong> <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
Travail <strong>de</strong> fin d’étu<strong><strong>de</strong>s</strong> présenté en vue <strong>de</strong> l’obtention du gra<strong>de</strong><br />
d’Ingénieur Civil en Informatique et Gestion<br />
Année académique 2006-2007<br />
Promoteurs:<br />
Prof. Pierre Manneback (FPMs) et Prof. Esteban Zimányi (ULB)
1<br />
à Brian
Table <strong><strong>de</strong>s</strong> matières<br />
1 Introduction 8<br />
1.1 Description du sujet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
1.2 Autres intérêts <strong>de</strong> l’ETL <strong>de</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . 8<br />
1.3 Structure <strong>de</strong> ce document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />
2 <strong>XML</strong> en bref 12<br />
2.1 <strong>XML</strong> : Rappel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />
2.1.1 Quelques règles élémentaires en <strong>XML</strong> . . . . . . . . . . . . . . . . . . 12<br />
2.1.2 Syntaxe d’un document <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . 13<br />
2.1.3 Déclaration d’un document <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . 13<br />
2.1.4 Exemple d’un document <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . 13<br />
2.2 Types et schémas <strong><strong>de</strong>s</strong> documents en <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . 14<br />
2.2.1 Document Type Definition - DTD . . . . . . . . . . . . . . . . . . . . 14<br />
2.2.2 <strong>XML</strong> Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />
2.3 Document <strong>XML</strong> bien formé et vali<strong>de</strong> . . . . . . . . . . . . . . . . . . . . . . . 15<br />
2.3.1 Document bien formé . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
2.3.2 Document vali<strong>de</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
2.4 Arborescence d’un document <strong>XML</strong> - DOM . . . . . . . . . . . . . . . . . . . 15<br />
2.5 Parcours d’un arbre <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />
2.6 Remarque importante sur l’utilisation <strong>de</strong> l’API DOM . . . . . . . . . . . . . . 16<br />
2.7 Transformation d’un document <strong>XML</strong> - XSLT . . . . . . . . . . . . . . . . . . 17<br />
3 Les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> <strong>XML</strong> 19<br />
3.1 Base <strong>de</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />
3.2 Stockage <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />
3.3 Classification <strong><strong>de</strong>s</strong> bases <strong>de</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . 19<br />
3.3.1 Base <strong>de</strong> <strong>données</strong> avec support <strong>XML</strong> . . . . . . . . . . . . . . . . . . . 19<br />
3.3.2 Base <strong>de</strong> <strong>données</strong> <strong>XML</strong> Native . . . . . . . . . . . . . . . . . . . . . . . 20<br />
3.4 Entrepôt <strong>de</strong> <strong>données</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />
3.4.1 Source <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>de</strong> l’entrepôt . . . . . . . . . . . . . . . . . . . . . 20<br />
3.4.2 Structure <strong>de</strong> <strong>données</strong> d’un entrepôt <strong>de</strong> <strong>données</strong> . . . . . . . . . . . . . 20<br />
3.4.3 Interrogation <strong>de</strong> l’entrepôt <strong>de</strong> <strong>données</strong> . . . . . . . . . . . . . . . . . . 20<br />
3.5 Entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />
3.6 Entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> et échange d’informations . . . . . . . . . . . . . . 22<br />
3.7 Entrepôt <strong>de</strong> <strong>données</strong> vs entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . . . . . 22<br />
2
TABLE DES MATIÈRES 3<br />
4 ETL : État <strong>de</strong> l’art 24<br />
4.1 Exécution parallèle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />
4.1.1 Un gros fichier source . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />
4.1.2 Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />
4.1.3 Plusieurs sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />
4.2 Evolution avec le temps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />
4.3 Compatibilité avec les systèmes d’exploitation . . . . . . . . . . . . . . . . . . 25<br />
4.4 ETL spatial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />
4.5 Quelques logiciels ETL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />
4.5.1 ETLs propriétaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />
4.5.2 ETLs open source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />
5 Schéma <strong>XML</strong> canonique pour un processus ETL 28<br />
5.1 Motivations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28<br />
5.2 Difficulté d’extraire une structure définie <strong>dans</strong> un schéma . . . . . . . . . . . 29<br />
5.3 Eviter les redondances <strong>dans</strong> les schémas . . . . . . . . . . . . . . . . . . . . . 30<br />
5.4 Règles génerales d’écriture d’un XSD . . . . . . . . . . . . . . . . . . . . . . . 31<br />
5.4.1 Un élément <strong>de</strong> type simple . . . . . . . . . . . . . . . . . . . . . . . . 31<br />
5.4.2 Un élément <strong>de</strong> type complexe . . . . . . . . . . . . . . . . . . . . . . . 32<br />
5.5 Règles canoniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />
5.6 Comment parcourir un schéma canonique . . . . . . . . . . . . . . . . . . . . 34<br />
6 Générateur automatique <strong>de</strong> fichier XSLT 35<br />
6.1 XPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />
6.2 XQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />
6.2.1 Ouverture <strong><strong>de</strong>s</strong> fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />
6.2.2 Expressions FLWOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />
6.3 XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />
6.3.1 Déclaration d’un document XSLT . . . . . . . . . . . . . . . . . . . . 36<br />
6.3.2 Quelques notions <strong>de</strong> base . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />
6.4 Pourquoi XSLT et pas XQuery ? . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />
6.5 Comment générer un fichier XSLT automatiquement . . . . . . . . . . . . . . 38<br />
6.5.1 Programme principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />
6.5.2 Co<strong>de</strong> XSLT selon la transformation <strong>de</strong>mandée . . . . . . . . . . . . . 39<br />
6.5.3 Transformation <strong><strong>de</strong>s</strong> attributs <strong>de</strong> l’élément courant . . . . . . . . . . . 40<br />
6.5.4 Comment trouver l’élément ou l’attribut correspondant ? . . . . . . . . 40<br />
6.6 Autres opérations possibles . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />
6.6.1 Opérateur <strong>de</strong> fusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />
6.6.2 Opérateur <strong>de</strong> séparation . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />
6.6.3 Opérateur <strong>de</strong> transformation d’un élément en attribut . . . . . . . . . 42<br />
6.6.4 Opérateur <strong>de</strong> vérification <strong>de</strong> compatibilité . . . . . . . . . . . . . . . . 42<br />
6.6.5 Opérateurs arithmétiques . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />
6.6.6 Opérateur <strong>de</strong> manipulation <strong><strong>de</strong>s</strong> instructions <strong>de</strong> traitement . . . . . . . 43<br />
6.6.7 Opérateurs d’exécution paralèlle d’un processus ETL . . . . . . . . . . 43
TABLE DES MATIÈRES 4<br />
7 Réalisation <strong>de</strong> l’ETL 44<br />
7.1 Quelques algorithmes du processus ETL <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . 44<br />
7.1.1 Vérifier si un type est prédéfini en XSD . . . . . . . . . . . . . . . . . 44<br />
7.1.2 Vérifier si un tag <strong>de</strong> XSD définit un élément . . . . . . . . . . . . . . . 45<br />
7.1.3 Vérifier si un tag <strong>de</strong> XSD définit un attribut . . . . . . . . . . . . . . 45<br />
7.1.4 Extraction du nom d’un élément, attribut ou type défini . . . . . . . . 45<br />
7.1.5 Extraction du type <strong>de</strong> l’élément ou <strong>de</strong> l’attribut défini . . . . . . . . . 46<br />
7.1.6 Traitement d’un élément et <strong>de</strong> ses fils directs . . . . . . . . . . . . . . 46<br />
7.1.7 Chargement <strong><strong>de</strong>s</strong> schémas . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />
7.1.8 Extraction <strong><strong>de</strong>s</strong> éléments et attributs définis <strong>dans</strong> un XSD . . . . . . . 47<br />
7.1.9 Parsing d’un noeud et <strong>de</strong> ses fils éventuels . . . . . . . . . . . . . . . . 48<br />
7.1.10 Parsing <strong>de</strong> la structure définie <strong>dans</strong> un fichier XSD . . . . . . . . . . . 49<br />
7.1.11 Création <strong>de</strong> l’interface <strong><strong>de</strong>s</strong> correspondances . . . . . . . . . . . . . . . 49<br />
7.1.12 Compilation d’un processus ETL . . . . . . . . . . . . . . . . . . . . . 49<br />
7.2 Prototype ETL développé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />
8 Exemple d’application 51<br />
8.1 Chargement <strong><strong>de</strong>s</strong> fichiers <strong>dans</strong> l’ETL . . . . . . . . . . . . . . . . . . . . . . . 51<br />
8.2 Visualisation <strong><strong>de</strong>s</strong> schémas chargés . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />
8.3 Un choix <strong>de</strong> correspondances . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />
8.4 Un autre choix <strong>de</strong> correspondances . . . . . . . . . . . . . . . . . . . . . . . . 55<br />
9 Conclusions et perspectives 58<br />
9.1 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58<br />
9.2 Perspectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />
Bibliographie 60<br />
A Co<strong>de</strong> PHP5 du prototype ETL développé 61<br />
A.1 Fichier in<strong>de</strong>x.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />
A.2 Fichier viewsrc.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
A.3 Fichier viewdst.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
A.4 Fichier mapping.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />
B Co<strong>de</strong> source <strong>de</strong> la classe XmlTransform 65
Table <strong><strong>de</strong>s</strong> figures<br />
1.1 Le processus ETL <strong>dans</strong> un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> . . . . . . . . . . . . . . 9<br />
1.2 Exportation/importation <strong>de</strong> <strong>données</strong> d’un SGBD à un autre . . . . . . . . . . 10<br />
1.3 Transformation d’un document GML en SVG . . . . . . . . . . . . . . . . . . 10<br />
2.1 Exemple d’une arborescence <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . . 16<br />
2.2 Parcours d’un arbre <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />
2.3 Illustration <strong><strong>de</strong>s</strong> noeuds réellement obtenus avec l’API DOM . . . . . . . . . . 18<br />
3.1 Exemple <strong>de</strong> l’entrepôt <strong>de</strong> <strong>données</strong> d’Arizona State University [14] . . . . . . . 21<br />
3.2 Exemple d’un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> : DAWAX [3] . . . . . . . . . . . . . 22<br />
6.1 Interface <strong><strong>de</strong>s</strong> correspondances . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />
8.1 Page d’accueil <strong>de</strong> <strong>XML</strong> ETL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />
8.2 Visualisation <strong><strong>de</strong>s</strong> arborescences définies <strong>dans</strong> les schémas . . . . . . . . . . . . 53<br />
8.3 Un choix d’une transformation . . . . . . . . . . . . . . . . . . . . . . . . . . 54<br />
8.4 Un autre choix <strong>de</strong> transformation . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />
5
Listings<br />
2.1 Exemple d’un document <strong>XML</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />
2.2 Exemple d’une DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />
2.3 Exemple d’un <strong>XML</strong> Schema -XSD . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
5.1 Visualisation <strong>de</strong> la structure définie <strong>dans</strong> le listing 2.3 . . . . . . . . . . . . . 28<br />
5.2 Autre façon d’écrire le schéma du listing 2.3 . . . . . . . . . . . . . . . . . . . 29<br />
5.3 Encore une autre manière d’écrire le schéma du listing 2.3 . . . . . . . . . . . 29<br />
5.4 Illustration <strong><strong>de</strong>s</strong> redondances <strong>dans</strong> un XSD . . . . . . . . . . . . . . . . . . . . 30<br />
5.5 Exemple <strong>de</strong> définition d’un élément <strong>de</strong> type complexe . . . . . . . . . . . . . 33<br />
5.6 Exemple d’un schéma canonique . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />
6.1 La fonction qui génère le fichier XSLT . . . . . . . . . . . . . . . . . . . . . . 38<br />
6.2 Production du co<strong>de</strong> XSLT selon le type <strong>de</strong> transformation choisie . . . . . . . 39<br />
6.3 Production du co<strong>de</strong> XSLT pour transformer les attributs <strong>de</strong> l’élément courant 40<br />
7.1 Algorithme testant si un type est prédéfini . . . . . . . . . . . . . . . . . . . . 44<br />
7.2 Algorithme testant si un tag XSD définit un élément . . . . . . . . . . . . . . 45<br />
7.3 Algorithme testant si un tag XSD définit un attribut . . . . . . . . . . . . . . 45<br />
7.4 Algorithme d’extraction du nom <strong>de</strong> l’élément/attribut/type complexe défini . 45<br />
7.5 Extraction du type <strong>de</strong> l’élément ou attribut défini . . . . . . . . . . . . . . . . 46<br />
7.6 Traitement <strong>de</strong> l’élément défini et <strong>de</strong> ses fils . . . . . . . . . . . . . . . . . . . 46<br />
7.7 Traitement <strong>de</strong> l’élément défini et <strong>de</strong> ses fils . . . . . . . . . . . . . . . . . . . 47<br />
7.8 Parsing d’une branche d’un arbre défini <strong>dans</strong> un XSD . . . . . . . . . . . . . 48<br />
7.9 Parsing d’une structure définie <strong>dans</strong> un fichier XSD . . . . . . . . . . . . . . . 49<br />
7.10 Compilation d’un processus ETL . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />
8.1 Schema XSD d’une source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />
8.2 Données <strong>XML</strong> d’une source . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />
8.3 XSLT généré suite aux choix du paragraphe 8.3 . . . . . . . . . . . . . . . . . 53<br />
8.4 Résultat du processus ETL du paragraphe 8.3 sur les <strong>données</strong> du listing 8.2 . 55<br />
8.5 Schéma <strong>de</strong> <strong><strong>de</strong>s</strong>tination du processus ETL du paragraphe 8.4 . . . . . . . . . . 55<br />
8.6 XSLT généré suite aux choix du paragraphe 8.4 . . . . . . . . . . . . . . . . . 56<br />
8.7 Résultats <strong>de</strong> l’ETL éxécuté au paragraphe 8.4 . . . . . . . . . . . . . . . . . . 56<br />
A.1 Fichier In<strong>de</strong>x.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />
A.2 Fichier viewsrc.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
A.3 Fichier viewdst.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
A.4 Fichier mapping.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />
B.1 Fichier xmletl2.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />
6
Remerciements<br />
J’aimerais tout d’abord remercier mes promoteurs Pierre Manneback et Esteban Zimányi,<br />
tous les <strong>de</strong>ux professeurs, respectivement, à la Faculté Polytechnique <strong>de</strong> Mons (FPMs) et à<br />
l’<strong>Université</strong> <strong>Libre</strong> <strong>de</strong> Bruxelles (ULB). Leurs encouragements, conseils, suggestions, relectures<br />
et corrections ont vraiment été une ai<strong>de</strong> précieuse pour la réalisation du présent mémoire.<br />
Je remercie également monsieur le professeur Philippe Fortemps, prési<strong>de</strong>nt <strong>de</strong> la section Informatique<br />
et Gestion, <strong>de</strong> m’avoir suggéré monsieur Manneback pour superviser ce travail<br />
proposé par monsieur Zimànyi.<br />
J’aimerais exprimer toute ma gratitute à ma famille et plus particulièrement à Jeannine<br />
et à Brian. Que cette oeuvre soit pour eux, le fruit <strong><strong>de</strong>s</strong> sacrifices qu’ils ont consenti pour me<br />
soutenir durant ces étu<strong><strong>de</strong>s</strong> qui s’achevent.<br />
Pour finir, je tiens à remercier tous mes collegues, amis et connaissances qui m’ont soutenu<br />
et aidé d’une manière ou d’une autre pour la réalisation <strong>de</strong> ce travail. Parmi eux, je peux citer<br />
monsieur Marc Okoko pour la relecture et les corrections ainsi que les membres du laboratoire<br />
Informatique et Réseaux <strong>de</strong> l’école polytechnique <strong>de</strong> l’ULB.<br />
7
Chapitre 1<br />
Introduction<br />
Ce chapitre positionne le sujet <strong>dans</strong> son contexte. Il montre d’une manière non exhaustive,<br />
quelques domaines confrontés aux problèmes pouvant être résolus par l’outil que nous<br />
proposons.<br />
1.1 Description du sujet<br />
Les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> 1 constituent <strong>de</strong> nos jours l’infrastructure <strong>de</strong> base <strong><strong>de</strong>s</strong> systèmes<br />
d’ai<strong>de</strong> à la décision. Ils permettent <strong>de</strong> gar<strong>de</strong>r <strong><strong>de</strong>s</strong> grands volumes d’informations historiques<br />
permettant ainsi <strong>de</strong> découvrir <strong><strong>de</strong>s</strong> tendances et <strong><strong>de</strong>s</strong> informations similaires qui sont indispensables<br />
aux organisations.<br />
Les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> obtiennent leurs informations <strong><strong>de</strong>s</strong> bases <strong>de</strong> <strong>données</strong> opérationnelles,<br />
c’est-à-dire, <strong><strong>de</strong>s</strong> bases <strong>de</strong> <strong>données</strong> qui supportent les opérations journalières <strong><strong>de</strong>s</strong> organisations.<br />
Pour amener ces informations à l’entrepôt, un processus communément appelé Extraction,<br />
Transformation et Load (ETL) est nécessaire. Celui-ci extrait les informations <strong><strong>de</strong>s</strong> systèmes<br />
opérationnels divers, les transforme <strong>de</strong> telle sorte qu’elles puissent respecter aussi bien les<br />
règles que les formats <strong>de</strong> l’entrepôt et les charge finalement <strong>dans</strong> ce <strong>de</strong>rnier.<br />
Actuellement, le processus <strong>de</strong> ETL ainsi que les outils logiciels qui facilitent ce processus<br />
travaillent sur <strong><strong>de</strong>s</strong> bases <strong>de</strong> <strong>données</strong> relationnelles. Le but du mémoire est la définition d’un<br />
processus ETL (voir la figure 1.1) et le développement d’un prototype d’outil associé qui<br />
permet d’interroger <strong><strong>de</strong>s</strong> sources <strong>de</strong> <strong>données</strong> <strong>XML</strong> en vue d’alimenter un entrepôt <strong>de</strong> <strong>données</strong><br />
également en <strong>XML</strong>.<br />
1.2 Autres intérêts <strong>de</strong> l’ETL <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
En <strong>de</strong>hors <strong><strong>de</strong>s</strong> <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong>, le besoin <strong>de</strong> l’ETL <strong>de</strong> <strong>données</strong> <strong>XML</strong> peut se faire<br />
sentir <strong>dans</strong> plusieurs domaines dont<br />
Exportation/Importation <strong>de</strong> <strong>données</strong> : Lorsqu’on exporte les informations d’une base<br />
<strong>de</strong> <strong>données</strong> (BD) à une autre (voir la figure 1.2), on est souvent confronté à plusieurs<br />
problèmes tels que :<br />
– la différence <strong><strong>de</strong>s</strong> schémas ;<br />
1 Data Warehouses<br />
8
CHAPITRE 1. INTRODUCTION 9<br />
<strong>XML</strong><br />
Source 1<br />
(Schema 1)<br />
<strong>XML</strong><br />
Source 2<br />
(Schema 2)<br />
ETL<br />
<strong>XML</strong><br />
Data Warehouse<br />
(Schema of DW)<br />
<strong>XML</strong><br />
Source X<br />
(Schema X)<br />
Fig. 1.1 – Le processus ETL <strong>dans</strong> un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
– le Système <strong>de</strong> Gestion <strong>de</strong> Base <strong>de</strong> Données (SGBD) source n’est pas toujours le même<br />
que celui <strong>de</strong> <strong><strong>de</strong>s</strong>tination ;<br />
– le type ou le format <strong>de</strong> <strong>données</strong> peut être différent. Exemple : d’un côté une date est<br />
codée <strong>dans</strong> une chaîne <strong>de</strong> caractères (05-07-2007) <strong>de</strong> l’autre, on co<strong>de</strong> la date sur 3<br />
nombres entiers (jours, mois, année) ;<br />
– etc.<br />
Dans les bases <strong>de</strong> <strong>données</strong> relationnelles par exemple, il faut connaître la structure <strong><strong>de</strong>s</strong><br />
tables pour bien écrire les requêtes permettant d’extraire les informations. Si pour une<br />
raison ou une autre, le schéma <strong>de</strong> la base <strong>de</strong> <strong>données</strong> ou les formats <strong><strong>de</strong>s</strong> informations<br />
désirées change, il faut modifier ou adapter une à une les requêtes utilisées.<br />
Comme la plupart <strong><strong>de</strong>s</strong> SGBD actuels sont dotés d’un outil permettant d’exporter/importer<br />
les <strong>données</strong> en <strong>XML</strong>, un outil ETL pourrait se charger du passage automatique<br />
d’un schéma/format à un autre. Ce qui permettrait une automatisation <strong>de</strong> l’ensemble<br />
du processus.<br />
Traitement <strong>de</strong> <strong>données</strong> géographiques : Le langage GML (Geography Markup Language)<br />
permet d’enco<strong>de</strong>r <strong><strong>de</strong>s</strong> informations géographiques. Malheureusement, pour visualiser ces<br />
<strong>données</strong> <strong>de</strong> manière graphique (cartes, ...), on a souvent besoin <strong>de</strong> les mettre sous un<br />
autre format comme SVG (Scalable Vector Graphics), X3D (eXtensible 3D) 2 , etc. Ces<br />
langages (GML, SVG, X3D) utilisant le formalisme <strong>XML</strong>, on effectue souvent cette<br />
transformation au moyen d’un fichier XSLT qu’il faut écrire soi-même.<br />
2 X3D est un format <strong>de</strong> fichier graphique et multimédia orienté 3D. Il peut être exprimé à l’ai<strong>de</strong> d’une<br />
syntaxe basée sur <strong>XML</strong> [16]. Voir http ://www.web3d.org pour plus d’informations sur X3D
CHAPITRE 1. INTRODUCTION 10<br />
etc.<br />
SGBD1<br />
<strong>XML</strong><br />
source<br />
ETL<br />
SGBD2<br />
<strong>XML</strong><br />
Destination<br />
Fig. 1.2 – Exportation/importation <strong>de</strong> <strong>données</strong> d’un SGBD à un autre<br />
GML<br />
source<br />
ETL<br />
SVG<br />
Destination<br />
Fig. 1.3 – Transformation d’un document GML en SVG<br />
D’un fichier <strong>de</strong> type <strong>XML</strong> vers un autre fichier <strong>de</strong> type <strong>XML</strong>, on peut utiliser un outil<br />
ETL qui aura comme source, le document GML et pour <strong><strong>de</strong>s</strong>tination, un document SVG<br />
ou X3D (voir la figure 1.3).<br />
1.3 Structure <strong>de</strong> ce document<br />
Outre ce premier chapitre introductif, le présent ouvrage est structuré <strong>de</strong> la manière<br />
suivante.<br />
– Un survol du langage <strong>XML</strong> sera donné au chapitre 2,<br />
– Le chapitre 3 introduira ensuite, les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> <strong>XML</strong>.<br />
– L’état <strong>de</strong> l’art du processus ETL sera donné au chapitre 4.<br />
– Au chapitre 5, nous expliquons une façon d’écrire un schéma <strong>XML</strong> (<strong>XML</strong> Schema) pour<br />
simplifier le parcours <strong>de</strong> son arborescence <strong>dans</strong> le cadre d’un processus ETL.<br />
– La conception d’un générateur automatique <strong>de</strong> fichier XSLT à partir <strong><strong>de</strong>s</strong> schémas <strong>XML</strong><br />
source et <strong><strong>de</strong>s</strong>tination sera abordée au chapitre 6.<br />
– Le chapitre 7 couvrira la réalisation d’un processus ETL à partir d’un fichier XSLT<br />
généré au chaipitre 6.<br />
– Une illustration du prototype ETL développé sera donnée au chapitre 8 sous forme d’un
CHAPITRE 1. INTRODUCTION 11<br />
exemple d’application.<br />
– Au chapitre 9, nous tirerons <strong><strong>de</strong>s</strong> conclusions et proposerons quelques pistes <strong>de</strong> recherche<br />
pour le futur.<br />
Compte tenu <strong>de</strong> la limitation du nombre 3 <strong>de</strong> pages <strong>dans</strong> un travail <strong>de</strong> fin d’étu<strong><strong>de</strong>s</strong> imposée<br />
par la faculté, le présent ouvrage est rédigé <strong>de</strong> manière à se focaliser essentiellement sur le<br />
processus ETL que nous proposons.<br />
3 +/- 50 pages
Chapitre 2<br />
<strong>XML</strong> en bref<br />
Vous trouverez <strong>dans</strong> ce chapitre, un petit rappel sur le <strong>XML</strong>. Le but n’est pas <strong>de</strong> nous<br />
étendre sur ce sujet très vaste et que nous supposerons connu mais, <strong>de</strong> rappeler quelques<br />
notions fondamentales nécessaires à la compréhension <strong>de</strong> la suite du présent travail.<br />
2.1 <strong>XML</strong> : Rappel<br />
<strong>XML</strong> (eXten<strong>de</strong>d Markup Language) est<br />
– un langage <strong>de</strong> balisage extensible,<br />
– un langage du style HTML,<br />
– un <strong><strong>de</strong>s</strong>cendant <strong>de</strong> SGML (Standard Generalized Markup Language)<br />
– un langage qui définit un cadre <strong>de</strong> représentation générique <strong>de</strong> <strong>données</strong> (semi-)structurées<br />
[19],<br />
– une famille <strong>de</strong> technologies qui peut tout faire <strong>de</strong>puis le formatage <strong>de</strong> document jusqu’au<br />
filtrage <strong>de</strong> <strong>données</strong> [13],<br />
– un ensemble <strong>de</strong> règles permettant <strong>de</strong> créer ses propres balises [13]<br />
et qui facile l’échange automatisé <strong><strong>de</strong>s</strong> informations entre systèmes (d’informations) hétérogènes<br />
(sur Internet).<br />
2.1.1 Quelques règles élémentaires en <strong>XML</strong><br />
Un document <strong>XML</strong> est essentiellement composé <strong>de</strong> tags 1 . Ces <strong>de</strong>rniers forment les éléments.<br />
Exemple d’un tag ouvrant : . Le tag fermant correspondant est .<br />
Un élément est constitué d’un tag ouvrant, du tag fermant correspondant et d’un contenu<br />
éventuel. Le contenu d’un élément peut être d’autres éléments, <strong>de</strong> <strong>données</strong> ou du texte [9].<br />
Dans ce cas, une balise fermante est obligatoire. Exemple Brian.<br />
Lorsqu’un élément est vi<strong>de</strong> (c’est-à-dire, n’a pas <strong>de</strong> contenu), on peut l’écrire<br />
– sous la forme d’une annotation d’ouverture et d’une <strong>de</strong> fermeture<br />
(exemple : )<br />
– ou sous la forme contractée (exemple : ).<br />
En <strong>XML</strong>, les Tags (annotations) respectent les règles suivantes [9, 13]<br />
– sensibilité à la casse. C’est-à-dire que les majuscules sont différenciées <strong><strong>de</strong>s</strong> minuscules.<br />
Le tag est différent <strong>de</strong> , lui-même différent <strong>de</strong> , etc.<br />
1 annotations ou balises<br />
12
CHAPITRE 2. <strong>XML</strong> EN BREF 13<br />
– Le premier caractère du nom d’un tag doit être une lettre ou un soulignement ( )<br />
– Le caractère blanc n’est pas permis au début du tag mais à la fin.<br />
– Le nom peut être composé <strong><strong>de</strong>s</strong> caractères alphanumériques,-,.,_.<br />
2.1.2 Syntaxe d’un document <strong>XML</strong><br />
Un document <strong>XML</strong> doit respecter les règles suivantes.<br />
– Avoir un et un seul élément racine (Root Element). Cet élement est aussi appelé Document<br />
element [9]. C’est l’élement qui contient tout le contenu du document.<br />
– Les annotations d’ouverture et <strong>de</strong> fermeture doivent se correspondre [9, 19]. Si un tag<br />
est ouvert à l’intérieur d’un élement, il doit être fermé à l’intérieur <strong>de</strong> ce même élément.<br />
– Tout tag doit être fermé comme il faut (... ou ).<br />
– Les attributs sont <strong><strong>de</strong>s</strong> propriétés contenues <strong>dans</strong> l’annotation d’ouverture.<br />
– Dans un tag, <strong>de</strong>ux attributs ne peuvent pas porter un même nom [9, 13].<br />
– Il y a une valeur unique par attribut.<br />
– Un élément peut avoir plusieurs attributs [13].<br />
2.1.3 Déclaration d’un document <strong>XML</strong><br />
Un document <strong>XML</strong> est un fichier text dont la première ligne, appelée Déclaration <strong>XML</strong><br />
(<strong>XML</strong> Declaration) [9] est <strong>de</strong> la forme<br />
< ?xml version="1.0" ?><br />
où version précise le standard <strong>XML</strong> utilisé <strong>dans</strong> le document.<br />
On peut également spécifier le codage <strong><strong>de</strong>s</strong> caractères avec l’attribut encoding pour permettre<br />
une lecture correcte du document [13]. A ce qui concerne les langues <strong>de</strong> l’europe occi<strong>de</strong>ntale,<br />
on écrira :<br />
< ?xml version="1.0"encoding="ISO-8859-1" ?><br />
2.1.4 Exemple d’un document <strong>XML</strong><br />
Listing 2.1 – Exemple d’un document <strong>XML</strong><br />
<br />
< personslist ><br />
<br />
< firstname >Johnny <br />
< middlename >Shele <br />
< lastname >Tsheke <br />
<br />
<br />
< firstname >Pierre <br />
< middlename /><br />
< lastname > Manneback <br />
<br />
<br />
< firstname > Esteban <br />
< middlename > Borrageiros <br />
< lastname > Zimanyi <br />
<br />
CHAPITRE 2. <strong>XML</strong> EN BREF 14<br />
2.2 Types et schémas <strong><strong>de</strong>s</strong> documents en <strong>XML</strong><br />
<strong>XML</strong> permet <strong>de</strong> créer ses propres balises et <strong>de</strong> définir un modèle (une structure) auquel les<br />
documents doivent se conformer. On peut créer un modèle <strong>de</strong> document <strong>XML</strong> par Document<br />
Type Definition (DTD) ou par <strong>XML</strong> schema.<br />
2.2.1 Document Type Definition - DTD<br />
Une DTD est un modèle qui représente une classe <strong>de</strong> document [10] ou qui décrit les<br />
exigences structurales d’un document <strong>XML</strong> [9]. Il peut définir :<br />
– les éléments et attributs éventuels,<br />
– les éléments fils, leurs nombres et l’ordre <strong>dans</strong> lequel ils peuvent apparaître,<br />
– les valeurs possibles et éventuellement, par défaut prises par les éléments et/ou les<br />
attributs,<br />
– etc.<br />
Pour le document <strong>XML</strong> du listing 2.1, une DTD correspondant pourrait être celui du listing<br />
2.2<br />
Listing 2.2 – Exemple d’une DTD<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Le lecteur intéressé par les DTDs pourrait consulter [9, 10, 13] où il trouvera plus <strong>de</strong> détails.<br />
2.2.2 <strong>XML</strong> Schema<br />
<strong>XML</strong> Schema est une alternative aux DTDs, basée sur <strong>XML</strong> [13,15]. Il définit un modèle<br />
<strong>de</strong> contenu pour une classe <strong>de</strong> documents <strong>XML</strong> et présente plusieurs avantages par rapport<br />
aux DTDs :<br />
– il est écrit en <strong>XML</strong> [4, 9, 13, 15],<br />
– il permet <strong>de</strong> spécifier le type <strong>de</strong> <strong>données</strong> [4, 15],<br />
– il est extensible,<br />
– il supporte les espaces <strong>de</strong> noms,<br />
– etc.<br />
On parle <strong>de</strong> <strong>XML</strong> Schema Definition (XSD) pour désigner la grammaire <strong>de</strong> <strong>XML</strong> Schema.<br />
Devenu une recommandation 2 du W3C <strong>de</strong>puis le 2 Mai 2001 et étant plus riche et plus<br />
puissant, on admet actuellement que <strong>XML</strong> Schema sera le successeur <strong><strong>de</strong>s</strong> DTDs [15].<br />
C’est pour cette raison que nous n’utiliserons pas <strong>de</strong> DTD <strong>dans</strong> le cadre <strong>de</strong> ce travail <strong>de</strong> fin<br />
d’étu<strong><strong>de</strong>s</strong>. Nous ne considérerons que les schémas donnés en <strong>XML</strong> schema.<br />
Le lecteur trouvera quelques règles d’écriture <strong><strong>de</strong>s</strong> schémas XSD au chaiptre 5, p.28. Dans<br />
l’immédiat nous nous contentons <strong>de</strong> donner <strong>dans</strong> le listing 2.3, un exemple d’un <strong>XML</strong> Schema<br />
qui peut définir le document <strong>XML</strong> du listing 2.1.<br />
2 <strong>XML</strong> Schema est un standard W3C
CHAPITRE 2. <strong>XML</strong> EN BREF 15<br />
Listing 2.3 – Exemple d’un <strong>XML</strong> Schema -XSD<br />
<br />
<br />
< xs:schema xmlns:xs =" http: // www .w3.org /2001/ <strong>XML</strong>Schema "><br />
< xs:element name =" personslist " type =" personsListType "/><br />
< xs:complexType name =" personsListType "><br />
< xs:element name =" person " type =" personType "/><br />
<br />
< xs:complexType name =" personType "><br />
< xs:element name =" firstname " type =" xs:string "/><br />
< xs:element name =" middlename " type =" xs:string "/><br />
< xs:element name =" lastname " type =" xs:string " use =" require "/><br />
< xs:attribute name =" birthdate " type =" xs:date "/><br />
<br />
<br />
2.3 Document <strong>XML</strong> bien formé et vali<strong>de</strong><br />
2.3.1 Document bien formé<br />
Un document <strong>XML</strong> est dit bien formé 3 s’il est syntaxiquement correct [1, 2, 9, 15, 19] ;<br />
c’est-à-dire qu’il respecte les règles énoncées au paragraphe 2.1.2 (p. 13). Il est exigé que tout<br />
document <strong>XML</strong> à traiter soit bien formé.<br />
2.3.2 Document vali<strong>de</strong><br />
Un document <strong>XML</strong> sera dit vali<strong>de</strong> s’il est bien formé et conforme à la DTD ou au schéma<br />
<strong>XML</strong> (<strong>XML</strong> schema) qui définit sa structure. Cette condition est capitale <strong>dans</strong> la conception<br />
et l’implémentation <strong>de</strong> l’ETL parce qu’il faut veuiller à ce que les informations importées <strong>dans</strong><br />
l’entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> soient stockées en conformité avec les exigences du schéma <strong>de</strong> ce<br />
<strong>de</strong>rnier. Dans la suite du présent travail, nous supposerons que le document <strong>XML</strong> <strong>de</strong> <strong>données</strong><br />
est vali<strong>de</strong> à la source (Base <strong>de</strong> <strong>données</strong> opérationnelle).<br />
2.4 Arborescence d’un document <strong>XML</strong> - DOM<br />
Les <strong>de</strong>ux API (Application Programming Interface) les plus utilisées pour accé<strong>de</strong>r aux<br />
<strong>données</strong> et aux structures <strong><strong>de</strong>s</strong> documents <strong>XML</strong> sont le DOM (Document Object Mo<strong>de</strong>l) et<br />
le SAX (Simple API for <strong>XML</strong>). Dans ce travail, nous utiliserons le DOM qui présente un<br />
document <strong>XML</strong> <strong>dans</strong> une structure arborescente où les éléments, les attributs et les textes<br />
sont définis comme <strong><strong>de</strong>s</strong> noeuds [15]. Cette structure est facile à manipuler et offre une certaine<br />
aisance à accé<strong>de</strong>r à n’importe quelle partie du document. Ceci nous sera particulièrement<br />
important pour l’implémentation <strong>de</strong> l’interface graphique 4 à partir <strong>de</strong> laquelle l’utilisateur<br />
3 En Anglais, on dit Well formed<br />
4 Le fichier XSLT sera généré en fonction <strong><strong>de</strong>s</strong> choix faits sur cette interface
CHAPITRE 2. <strong>XML</strong> EN BREF 16<br />
choisira les types d’informations à importer <strong>dans</strong> l’entrepôt <strong>de</strong> <strong>données</strong>.<br />
Nous n’avons pas l’intention <strong>de</strong> nous attar<strong>de</strong>r sur le DOM. Nous voulons tout simplement<br />
donner à la figure 2.1 une illustration <strong>de</strong> l’arborescence correspondant au document <strong>XML</strong> du<br />
listing 2.1 (p. 13)<br />
(Element)<br />
firstname<br />
(Text)<br />
Johnny<br />
(Element)<br />
person<br />
(Element)<br />
middlename<br />
(Text)<br />
Shele<br />
(Element)<br />
lastname<br />
(Text)<br />
Tsheke<br />
(Element)<br />
firstname<br />
(Text)<br />
Pierre<br />
(Root Element)<br />
personslist<br />
(Element)<br />
person<br />
(Element)<br />
middlename<br />
(Element)<br />
lastname<br />
(Text)<br />
Manneback<br />
(Element)<br />
firstname<br />
(Text)<br />
Esteban<br />
Fig. 2.1 – Exemple d’une arborescence <strong>XML</strong><br />
2.5 Parcours d’un arbre <strong>XML</strong><br />
(Element)<br />
person<br />
(Element)<br />
middlename<br />
(Text)<br />
Borrageiros<br />
Dans un arbre <strong>de</strong> représentation d’un document <strong>XML</strong> [15] :<br />
– Le noeud supérieur (le premier noeud) est appelé Racine (Root),<br />
– Un noeud ascendant est appelé parent,<br />
– Un noeud <strong><strong>de</strong>s</strong>cendant est appelé enfant (child),<br />
– A part la racine, chaque noeud a un et un seul parent direct (père),<br />
– Un noeud peut avoir 0 ou plusieurs enfants,<br />
– Une feuille est un noeud qui n’a pas d’enfant,<br />
– Les noeuds déscendants d’un même père (direct) sont dits frères (siblings).<br />
A partir d’un noeud, on peut parcourir l’arbre d’une <strong><strong>de</strong>s</strong> manières suivantes.<br />
– En allant vers un <strong><strong>de</strong>s</strong>cendant (child). Ceci n’est pas possible pour une feuille.<br />
– En allant vers un frère (next, previous) si possible.<br />
– En remontant vers le noeud père (parent) si on n’est pas à la racine.<br />
La figure 2.2 illustre le parcours d’une partie <strong>de</strong> l’arbre <strong>de</strong> la figure 2.1.<br />
2.6 Remarque importante sur l’utilisation <strong>de</strong> l’API DOM<br />
(Element)<br />
lastname<br />
(Text)<br />
Zimanyi<br />
Nous attirons l’attention du lecteur et plus précisement du programmeur sur le fait<br />
qu’indépendamment <strong>de</strong> la validité du document (voir paragraphe 2.3.2), la manipulation<br />
<strong>de</strong> l’arbre <strong>XML</strong> avec l’API DOM retourne (en PHP, JAVA, ...) <strong><strong>de</strong>s</strong> noeuds Text <strong>de</strong> part et<br />
d’autre d’un noeud Element. Sauf l’élément racine (Root Element) qui apparaît comme un<br />
fils du noeud document (Document) [11, 12].<br />
Il sera particulièrement utile <strong>de</strong> tenir compte <strong>de</strong> cette réalité lors du processing <strong><strong>de</strong>s</strong> schémas<br />
XSD en vue <strong>de</strong> générer un fichier XSLT automatiquement. Pour l’arbre <strong>de</strong> la figure 2.2, on<br />
obtiendrait en réalité celui <strong>de</strong> la figure 2.3. Il faut donc être attentif <strong>dans</strong> la sélection <strong><strong>de</strong>s</strong>
CHAPITRE 2. <strong>XML</strong> EN BREF 17<br />
(Root Element)<br />
personslist<br />
firstChild<br />
lastChild<br />
(Element)<br />
person<br />
(Element)<br />
person<br />
(Element)<br />
person<br />
parent<br />
children<br />
(Element)<br />
firstname<br />
(Element)<br />
middlename<br />
(Element)<br />
lastname<br />
Fig. 2.2 – Parcours d’un arbre <strong>XML</strong><br />
parent<br />
parent<br />
(Text)<br />
Pierre<br />
(Text)<br />
Manneback<br />
noeuds utiles pour éviter <strong><strong>de</strong>s</strong> surprises.<br />
Les algorithmes proposés <strong>dans</strong> la suite permettront <strong>de</strong> résoudre ce problème <strong>dans</strong> le cadre <strong>de</strong><br />
l’ETL. De manière plus générale, on peut tester le type du noeud présent puis effectuer un<br />
traitement approprié. Les personnes confrontées à ce problème pourront consulter [12].<br />
2.7 Transformation d’un document <strong>XML</strong> - XSLT<br />
La transformation est l’opération par laquelle on convertit un document <strong>XML</strong> (source)<br />
<strong>dans</strong> un autre format (<strong><strong>de</strong>s</strong>tination) : HTML, <strong>XML</strong>,etc. Le langage <strong>de</strong> programmation le plus<br />
utilisé à cet effet est le XSL Transformation (XSLT).<br />
XSL (Extensible Stylesheet Language) est la composition <strong><strong>de</strong>s</strong> trois langages :<br />
– XSLT,<br />
– XPath qui permet <strong>de</strong> parcourir l’arbre du document et<br />
– XSL-FO qui permet le formatage.<br />
Dans le cadre <strong>de</strong> cette conception <strong>de</strong> l’ETL <strong>de</strong> <strong>données</strong> <strong>XML</strong>, nous ne nous intéresserons qu’à<br />
XSLT et XPath dont nous donnerons un petit rappel au chapitre 6. Notre préoccupation est<br />
<strong>de</strong> transformer à l’ai<strong>de</strong> <strong>de</strong> XSLT, un arbre <strong>XML</strong> vali<strong>de</strong> par rapport au schéma source, en un<br />
arbre <strong>XML</strong> respectant le XSD <strong>de</strong> l’entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> (<strong><strong>de</strong>s</strong>tination). Les expressions<br />
XPath seront utilisées pour naviguer <strong>dans</strong> le document.
CHAPITRE 2. <strong>XML</strong> EN BREF 18<br />
(Document)<br />
(Root Element)<br />
personslist<br />
firstChild<br />
lastChild<br />
(Text)<br />
(Element)<br />
person<br />
(Text)<br />
(Element)<br />
person<br />
(Text)<br />
(Element)<br />
person<br />
(Text)<br />
Fig. 2.3 – Illustration <strong><strong>de</strong>s</strong> noeuds réellement obtenus avec l’API DOM
Chapitre 3<br />
Les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
3.1 Base <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
On appelle base <strong>de</strong> <strong>données</strong> <strong>XML</strong>, un logiciel capable <strong>de</strong> stocker, importer, exporter et<br />
rendre accessible les <strong>données</strong> <strong>XML</strong> [18]. Le paragraphe 3.2 survole les manières <strong>de</strong> conserver<br />
ces types d’informations.<br />
3.2 Stockage <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>XML</strong><br />
Il y a plusieurs façons <strong>de</strong> stocker les <strong>données</strong> <strong>XML</strong>. Les techniques les plus utilisées sont<br />
les suivantes [3].<br />
– Dans <strong><strong>de</strong>s</strong> fichiers <strong>de</strong> type text : Les informations sont conservées <strong>dans</strong> les fichiers <strong>XML</strong><br />
par exemple. La gestion <strong>de</strong> ces fichiers peut se faire éventuellement <strong>dans</strong> <strong><strong>de</strong>s</strong> collections<br />
structurées elles-mêmes en hierarchie comme <strong>dans</strong> un système <strong>de</strong> fichier (Linux, Unix).<br />
– Dans une base <strong>de</strong> <strong>données</strong> traditionnelle : Ici, on extrait les <strong>données</strong> et on les gar<strong>de</strong> au<br />
format du SGBD. On utilisera <strong><strong>de</strong>s</strong> tables, par exemple, si on a affaire à une base <strong>de</strong><br />
<strong>données</strong> relationnelle. On veuillera à disposer d’un modèle <strong>de</strong> <strong>données</strong> pour permettre<br />
la restitution en <strong>XML</strong> au moment d’extraire les informations.<br />
– Dans un système hybri<strong>de</strong> : Cette technique fait le mixage <strong><strong>de</strong>s</strong> <strong>de</strong>ux approches précé<strong>de</strong>ntes.<br />
3.3 Classification <strong><strong>de</strong>s</strong> bases <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
On classifie habituellement les bases <strong>de</strong> <strong>données</strong> <strong>XML</strong> en <strong>de</strong>ux grands groupes : celles avec<br />
support <strong>XML</strong> et celles qu’on qualifie <strong>de</strong> natives.<br />
3.3.1 Base <strong>de</strong> <strong>données</strong> avec support <strong>XML</strong><br />
Dans ce groupe, on trouve les bases <strong>de</strong> <strong>données</strong> traditionnelles (relationnelle, objet, ...)<br />
– avec une couche ou interface permettant l’importation et/ou l’exportation <strong><strong>de</strong>s</strong> <strong>données</strong><br />
en <strong>XML</strong>,<br />
– et stockent ces informations au format du SGBD.<br />
En se basant sur le modèle DOM où un document <strong>XML</strong> peut être vu comme un arbre (un<br />
objet), on peut stocker ce <strong>de</strong>rnier comme un objet <strong>dans</strong> une base <strong>de</strong> <strong>données</strong> objet. Dans le<br />
19
CHAPITRE 3. LES ENTREPÔTS DE DONNÉES <strong>XML</strong> 20<br />
même ordre d’idées, en définissant une certaine correspondance entre le document <strong>XML</strong> et<br />
certaines tables, on peut enregistrer les <strong>données</strong> <strong>XML</strong> <strong>dans</strong> une BD relationnelle.<br />
3.3.2 Base <strong>de</strong> <strong>données</strong> <strong>XML</strong> Native<br />
Dans ce groupe, on définit un modèle logique du document en fonction <strong>de</strong> <strong>XML</strong> et on<br />
utilise un document <strong>XML</strong> comme unité fondamentale <strong>de</strong> stockage. Dans une base <strong>de</strong> <strong>données</strong><br />
relationnelle, on a une ligne <strong>de</strong> table comme unité <strong>de</strong> stockage. Mais, <strong>dans</strong> une base <strong>de</strong><br />
donnée <strong>XML</strong> Native (Native <strong>XML</strong> Database - NXD), c’est un document <strong>XML</strong> qui est l’unité<br />
<strong>de</strong> stockage [18]. Actuellement il existe plusieurs SGBD <strong>XML</strong> natifs : eXist, Apache XIndice,<br />
Tamino, ...<br />
3.4 Entrepôt <strong>de</strong> <strong>données</strong><br />
Dans une organisation, un entrépôt <strong>de</strong> <strong>données</strong> (Data Warehouse) est une base <strong>de</strong> <strong>données</strong><br />
intégrant <strong><strong>de</strong>s</strong> informations [19] :<br />
– issues <strong><strong>de</strong>s</strong> sources hétérogènes,<br />
– datées (historisées),<br />
– non modifiables (lecture seule),<br />
– et organisées <strong>de</strong> manière à permettre <strong><strong>de</strong>s</strong> analyses statistiques et une exploitation en<br />
gestion stratégique.<br />
La figure 3.1 illustre l’implémentation d’un entrepôt <strong>de</strong> <strong>données</strong> à l’université d’état d’Arizona<br />
aux USA (Arizona State University - ASU ).<br />
3.4.1 Source <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>de</strong> l’entrepôt<br />
Les <strong>données</strong> sont issues <strong><strong>de</strong>s</strong> BD opérationnelles qui ont, en général, <strong><strong>de</strong>s</strong> schémas différents.<br />
La mise à jour ne se fait pas toujours périodiquement mais parfois sporadiquement. Ces<br />
<strong>données</strong> seront agrégées pour éviter les redondances et permettre la facilité d’accès et d’analyse.<br />
3.4.2 Structure <strong>de</strong> <strong>données</strong> d’un entrepôt <strong>de</strong> <strong>données</strong><br />
Dans un entrepôt <strong>de</strong> <strong>données</strong>, les informations sont en géneral représentées <strong>dans</strong> un modèle<br />
<strong>de</strong> <strong>données</strong> en étoile ou en cube.<br />
3.4.3 Interrogation <strong>de</strong> l’entrepôt <strong>de</strong> <strong>données</strong><br />
Les <strong>de</strong>ux approches les plus utilisées sont<br />
– R-OLAP (Relational On-Line Analytical Porcessing) : lorsqu’on a <strong><strong>de</strong>s</strong> requêtes SQL et<br />
– M-OLAP (Multidimensional On-Line Analytical Porcessing) : si on a un modèle en cube<br />
<strong>de</strong> plusieurs dimensions.<br />
De manière plus générale, on parle <strong>de</strong> OLAP qui englobe aussi d’autres approches (H-OLAP 1 ,<br />
S-OLAP 2 et D-OLAP 3 ) 4<br />
1 Hybrid OLAP<br />
2 Spatial OLAP<br />
3 Dynamic ou Desktop OLAP<br />
4 Voir http ://fr.wikipedia.org/wiki/OLAP
CHAPITRE 3. LES ENTREPÔTS DE DONNÉES <strong>XML</strong> 21<br />
Fig. 3.1 – Exemple <strong>de</strong> l’entrepôt <strong>de</strong> <strong>données</strong> d’Arizona State University [14]<br />
3.5 Entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
Un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> est un entrepôt <strong>de</strong> <strong>données</strong> capable <strong>de</strong><br />
– accepter <strong><strong>de</strong>s</strong> sources <strong>de</strong> <strong>données</strong> <strong>XML</strong>,<br />
– fournir les <strong>données</strong> ou document <strong>XML</strong> en output,<br />
– supporter les techniques <strong>de</strong> manipulation habituelle <strong><strong>de</strong>s</strong> documents <strong>XML</strong> (XSLT, XPATH,<br />
...) et,<br />
– agréger les <strong>données</strong> issues <strong><strong>de</strong>s</strong> différentes sources <strong>de</strong> sorte qu’elles soient vali<strong><strong>de</strong>s</strong> par<br />
rapport aux schémas <strong>de</strong> stockage.<br />
La figure FIG.3.2 illustre l’entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> proposé <strong>dans</strong> [3]. Comme nous l’avons<br />
dit au paragraphe 3.2 (p.19), il y a plusieurs façons <strong>de</strong> stocker les documents <strong>XML</strong>. Cette<br />
réalité implique une diversité <strong>de</strong> manières d’implémenter un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong>. Dans<br />
ce chapitre, le but n’est pas d’expliquer la conception ou l’implémentation d’un entrepôt <strong>de</strong><br />
<strong>données</strong> <strong>XML</strong> <strong>dans</strong> sa globalité mais <strong>de</strong> donner un aperçu général.
CHAPITRE 3. LES ENTREPÔTS DE DONNÉES <strong>XML</strong> 22<br />
Fig. 3.2 – Exemple d’un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> : DAWAX [3]<br />
3.6 Entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> et échange d’informations<br />
Un <strong><strong>de</strong>s</strong> avantages que peut offrir un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> est notament la possibilité<br />
d’échanger les informations par http en intranet ou Internet. Grâce à la technologie <strong>XML</strong>, on<br />
peut utiliser <strong><strong>de</strong>s</strong> standards. Ce qui ne nécessite pas d’avoir une API propriétaire quelconque.<br />
Cette solution est particulièrement intéressante pour une organisation (societé mutinationale,<br />
grosse administration, ...) répartie sur plusieurs sites ou qui inter-agit avec <strong><strong>de</strong>s</strong> sous-traitants<br />
par exemple.<br />
On notera que la plupart <strong><strong>de</strong>s</strong> SGBD actuels prévoient au moins la possibilté d’intégrer les<br />
<strong>données</strong> <strong>XML</strong>. Dans SQL Server 2005, Integration Service [8] par exemple, malgré le stockage<br />
<strong><strong>de</strong>s</strong> informations <strong>dans</strong> une base <strong>de</strong> <strong>données</strong> relationnelles (SQL Server), on prévoit tout <strong>de</strong><br />
même la possibilité d’importer les <strong>données</strong> à partir d’une source <strong>XML</strong>. Cette source peut être<br />
locale (un fichier) ou distante (accessible par http). Nous verrons plus tard que cette stratégie<br />
s’intègre parfaitement <strong>dans</strong> l’outil ETL que nous proposons.<br />
3.7 Entrepôt <strong>de</strong> <strong>données</strong> vs entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
Dans la table 3.1 nous reprenons une synthèse d’éléments distinguant, <strong>de</strong> manière générale,<br />
un Entrepôt <strong>de</strong> <strong>données</strong> d’un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> [1]. Rappelons que <strong>dans</strong> la pratique, la<br />
différence est un peu nuancée parce que <strong>de</strong> nos jours, les systèmes mis réellement en production<br />
sont souvent hybri<strong><strong>de</strong>s</strong>. c’est-à-dire, qu’on essaie <strong>de</strong> combiner les différentes approches pour<br />
tirer au mieux les avantages <strong>de</strong> chacune. Après tout, chacun construit son entrepôt <strong>de</strong> <strong>données</strong><br />
(<strong>XML</strong>) selon ses besoins. Bill Inmon 5 n’aurait-il pas dit : “Un Data Warehouse ne s’achète<br />
5 On le considère généralement comme le père du concept Data Warehouse
CHAPITRE 3. LES ENTREPÔTS DE DONNÉES <strong>XML</strong> 23<br />
Entrepôt <strong>de</strong> <strong>données</strong> Entrpôt <strong>de</strong> <strong>données</strong> <strong>XML</strong><br />
Données Données relationnelles <strong>XML</strong><br />
Valeurs numériques texte<br />
Approvisionnement filtrage filtrage<br />
classification,<br />
semantique ...,<br />
Integration et vue relations <strong>XML</strong><br />
cube<br />
Interrogation SQL XQuery, XSLT<br />
Exploitation OLAP lecture<br />
outils statistiques production <strong><strong>de</strong>s</strong> rapports<br />
production <strong><strong>de</strong>s</strong> rapports<br />
Tab. 3.1 – Différence entre entrepôt <strong>de</strong> <strong>données</strong> et entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> [1]<br />
pas, il se construit” 6 . On peut donc utiliser telle ou telle autre technique pour mieux exploiter<br />
les <strong>données</strong>.<br />
6 http ://fr.wikipedia.org/wiki/Entrepôt <strong>de</strong> <strong>données</strong>
Chapitre 4<br />
ETL : État <strong>de</strong> l’art<br />
Dans ce chapitre, nous survolons l’état <strong>de</strong> l’art du processus ETL. Nous examinerons<br />
les possibilités offertes actuellement par l’évolution technologique. Ceci permettra <strong>de</strong> mieux<br />
comprendre par la suite la contribution qu’apporte la technique que nous proposons.<br />
4.1 Exécution parallèle<br />
Compte tenu du développement <strong><strong>de</strong>s</strong> technologies <strong>de</strong> l’information et <strong>de</strong> la communication,<br />
on est <strong>de</strong> plus en plus confronté à un volume <strong>de</strong> <strong>données</strong> important. Ceci néssecite d’adapter<br />
les techniques d’extraction et/ou <strong>de</strong> filtrage pour que l’outil ETL ne prenne pas trop <strong>de</strong><br />
temps.<br />
Actuellement, on utilise <strong>de</strong> plus en plus le parallélisme [17]. Ce <strong>de</strong>rnier peut s’appliquer<br />
lorsqu’il faut traiter :<br />
– un gros fichier source,<br />
– les <strong>données</strong> en pipeline ou<br />
– plusieurs sources <strong>de</strong> <strong>données</strong>.<br />
4.1.1 Un gros fichier source<br />
Lorsque les <strong>données</strong> <strong>de</strong> la source se trouvent <strong>dans</strong> un fichier séquentiel par exemple, la<br />
taille <strong>de</strong> ce <strong>de</strong>rnier peut avoir un impact non négligeable sur les applications qui doivent le<br />
manipuler. Dans le cas d’un fichier <strong>XML</strong>, si on utilise une API DOM, on risque <strong>de</strong> rencontrer<br />
<strong><strong>de</strong>s</strong> difficultés en voulant charger l’entièreté <strong>de</strong> l’arbre en mémoire.<br />
Les bases <strong>de</strong> <strong>données</strong> eXist par exemple, fonctionnent moins bien lorsque le nombre d’entrées<br />
<strong>de</strong>vient relativement important.<br />
Une solution consiste à découper (split) le fichier en <strong><strong>de</strong>s</strong> morceaux <strong>de</strong> tailles plus facilement<br />
manipulables. De cette manière, on peut accé<strong>de</strong>r à plusieurs parties simultanément.<br />
4.1.2 Pipeline<br />
La technique <strong>de</strong> pipeline permet <strong>de</strong> traiter plusieurs composants d’un même fichier simultanément.<br />
Pendant que l’on fait une opération ou une manipulation sur un élément on peut<br />
en même temps faire un autre traitement sur l’élément suivant.<br />
24
CHAPITRE 4. ETL : ÉTAT DE L’ART 25<br />
4.1.3 Plusieurs sources<br />
Lorsqu’on est en présence <strong>de</strong> plusieurs sources (fichiers), on peut envisager <strong>de</strong> traiter un<br />
certain nombre en parallèle. Si un processus est occupé à trier un fichier par exemple, on peut<br />
<strong>de</strong>man<strong>de</strong>r à un autre processus <strong>de</strong> supprimer les doublons d’un autre fichier.<br />
De cette manière on gagne en temps parce que le traitement du 2e fichier commence plus tôt<br />
que si on <strong>de</strong>vait attendre <strong>de</strong> finir le tri du 1er.<br />
Signalons tout <strong>de</strong> même que le Multi-processing/Multi-threading n’est pleinement opérationnel<br />
que sur <strong><strong>de</strong>s</strong> systèmes multi-processeurs ! Heureusement qu’aujourd’hui la plupart <strong><strong>de</strong>s</strong> machines<br />
supportant les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> sont multiprocesseurs.<br />
4.2 Evolution avec le temps<br />
Comme pour les autres logiciels, il est indispensable que l’outil ETL puisse évoluer avec le<br />
temps. On doit donc pouvoir le mettre à jour facilement et si possible gar<strong>de</strong>r la compatibilité<br />
avec les versions ou les applications antérieures. On doit par exemple pouvoir se connecter à<br />
<strong><strong>de</strong>s</strong> nouveaux SGBD capables <strong>de</strong> fournir <strong><strong>de</strong>s</strong> <strong>données</strong> au format supporté par l’ETL. Il faut<br />
également pouvoir supporter une mise à jour éventuelle du/<strong><strong>de</strong>s</strong> SGBD constituant l’entrepôt.<br />
Il convient <strong>de</strong> noter que les bases <strong>de</strong> <strong>données</strong> opérationnelles évoluent et qu’on pourrait<br />
vouloir gar<strong>de</strong>r <strong>dans</strong> l’entrepôt <strong><strong>de</strong>s</strong> informations auxquelles on n’avait pas songé au moment<br />
<strong>de</strong> l’implémentation <strong>de</strong> l’entrepôt <strong>de</strong> <strong>données</strong>. A titre d’exemple, à un moment, on peut<br />
vouloir conserver une liste <strong>de</strong> personnes (clientes) <strong>de</strong> l’étranger. Malheureusement, la structure<br />
d’adresse est différente <strong>de</strong> ce qu’on a prévu initialement (certains champs en plus ou en moins,<br />
...). Il faut que l’ETL puisse s’adapter très facilement <strong>dans</strong> ces genres <strong>de</strong> problèmes.<br />
4.3 Compatibilité avec les systèmes d’exploitation<br />
A part les ETL incorporés <strong>dans</strong> les produits Microsoft comme SQL Server Integration<br />
Service qui ne fonctionnent essentiellement que sous Windows, la plupart <strong><strong>de</strong>s</strong> fabricants essaient<br />
<strong>de</strong> rendre compatibles leurs produits avec un grand nombre <strong>de</strong> systèmes d’exploitation<br />
(Windows, Linux/Unix, Mac-OS, ...).<br />
Notre prototype a été développé en PHP. Ce qui permet <strong>de</strong> l’intégrer facilement <strong>dans</strong> n’importe<br />
quel serveur web supportant ce langage. On pourrait utiliser le serveur web Apache 1<br />
que l’on peut télécharger gratuitement sur le site http://httpd.apache.org.<br />
4.4 ETL spatial<br />
L’ETL spatial est poussé par le geographic information system (GIS) pour permettre<br />
l’interopérabilité entre les divers formats <strong><strong>de</strong>s</strong> <strong>données</strong> géographiques [17]. Malgré le fait que<br />
plusieurs fabricants <strong><strong>de</strong>s</strong> logiciels ETL commencent à incorporer les spécifications <strong>de</strong> l’ETL<br />
spatial, le problème est encore loin d’être résolu.<br />
Nous pensons tout <strong>de</strong> même que le noyau <strong>de</strong> notre ETL pourrait s’adapter aux besoins<br />
<strong>de</strong> GIS. En effet, comme nous l’avons dit précé<strong>de</strong>mment, plusieurs technologies actuelles<br />
supportent l’importation et l’exportation <strong>de</strong> <strong>données</strong> en <strong>XML</strong>. Le fait que notre ETL effectue<br />
1 Open source
CHAPITRE 4. ETL : ÉTAT DE L’ART 26<br />
une transformation <strong>de</strong> <strong>XML</strong> vers <strong>XML</strong> fait qu’on peut avoir une interopérabilité en allant<br />
séquentiellemment <strong>de</strong> la manière suivante.<br />
– exporter les <strong>données</strong> en <strong>XML</strong> (à partir <strong>de</strong> la source),<br />
– passer les <strong>données</strong> source <strong>XML</strong> <strong>dans</strong> l’ETL,<br />
– obtenir les <strong>données</strong> <strong><strong>de</strong>s</strong>tination <strong>XML</strong> conformes au schéma accepté par le système exploitant<br />
les <strong>données</strong>,<br />
– importer les <strong>données</strong> <strong>XML</strong> <strong>dans</strong> le système <strong>de</strong> <strong><strong>de</strong>s</strong>tination.<br />
On obtient ainsi les <strong>données</strong> <strong>dans</strong> l’autre format. Les figures 1.2 et 1.3 illustrent cette possibilité.<br />
4.5 Quelques logiciels ETL<br />
Dans cette section nous présentons quelques principaux logiciels ETL que l’on peut trouver<br />
actuellement sur le marché. La liste est loin d’être exhaustive mais elle donne une idée<br />
générale <strong><strong>de</strong>s</strong> tendances actuelles.<br />
Dans cette liste, nous distinguons les ETLs open source <strong><strong>de</strong>s</strong> ETLs propriétaires. Habituellement<br />
les prémiers sont téléchargeables gratuitement mais pour les autres, seule une version<br />
dévalution peut être téléchargée et installée <strong>de</strong> manière gratuite.<br />
4.5.1 ETLs propriétaires<br />
4.5.1.1 SQL Server Integration Services<br />
Le SQL Server 2005 Integration Services (SSIS) comporte un outil ETL permettant<br />
d’intégrer les <strong>données</strong> en provenance <strong><strong>de</strong>s</strong> diverses sources hétérogènes 2 . Comme SQL server<br />
2005 prend en charge les <strong>données</strong> <strong>XML</strong> en mo<strong>de</strong> natif, on peut manipuler ces types d’informations.<br />
Le problème est que cet outil ETL ne fonctionne que <strong>dans</strong> un SSIS qui ne peut lui même être<br />
installé que sous Windows. Ce qui ne permet pas <strong>de</strong> l’installer <strong>dans</strong> un autre environnement.<br />
4.5.1.2 Oracle Data Integrator<br />
Il s’agit d’un ETL <strong>de</strong> Oracle 3 pouvant tourner sur plusieurs systèmes d’exploitation. Il<br />
peut se connecter sur plusieurs plateformes d’entrepôt <strong>de</strong> <strong>données</strong> (Teradata, IBM DB, Oracle,<br />
...) ainsi qu’à <strong><strong>de</strong>s</strong> technologies ERP, LDAP, <strong>XML</strong>, etc. A l’origine, ce produit appartenait à<br />
la société Sunopsis 4 qui a été rachetée par Oracle en 2006.<br />
4.5.1.3 Oxio Data Integration<br />
La société française Oxio (http://www.oxio.fr) développe un ETL 100% web. Cette<br />
solution, comme <strong>dans</strong> notre prototype, a l’avantage <strong>de</strong> ne pas nécessiter <strong><strong>de</strong>s</strong> applications<br />
clientes. Il suffit <strong>de</strong> disposer d’un navigateur web et d’un accès réseau pour pourvoir utiliser<br />
l’application selon les autorisations accordées. Le fait qu’il soit développé en SQL server et<br />
.Net nous semble limiter les possibilités <strong>de</strong> son installation sur d’autres systèmes d’exploitation<br />
comme Linux, Mac-Os, etc.<br />
2 voir http://www.microsoft.com/france/sql/sql2005/<strong>de</strong>couvrez/presentation.mspx<br />
3 voir http://www.oracle.com<br />
4 voir http://www.oracle.com/sunopsis
CHAPITRE 4. ETL : ÉTAT DE L’ART 27<br />
4.5.2 ETLs open source<br />
4.5.2.1 Talend open studio<br />
Talend Open Studio est un ETL graphique et open source développé en Java/Eclipse. Pour<br />
un fichier <strong>XML</strong> se présentant en entrée, il le lit ligne par ligne pour le scin<strong>de</strong>r en champs et<br />
envoie ces <strong>de</strong>rniers tels que définis <strong>dans</strong> le schéma au composant suivant du job, via un lien<br />
Row.<br />
L’approche peut paraître relativement lente pour l’accès aux éléments mais si on tient compte<br />
<strong>de</strong> la lour<strong>de</strong>ur <strong><strong>de</strong>s</strong> applications java, il ne serait peut-être pas optimal d’envisager le chargement<br />
d’un grand-t-arbre <strong>XML</strong> en mémoire. Le lecteur trouvera plus d’informations sur<br />
http://www.talend.com.<br />
4.5.2.2 Scriptella<br />
Scriptella (http://scriptella.javaforge.com) est un ETL open source développé en<br />
java. Il nous a semblé relativement moins approprié pour une production réelle. En effet, il<br />
utilise essentiellement le SQL pour les transformations. Ce qui n’est pas spécialement adapté<br />
pour les <strong>données</strong> <strong>XML</strong>. Il faut <strong>de</strong> toutes les façons aller éditer un fichier <strong>XML</strong> pour préciser<br />
les informations <strong>de</strong> connexion (host, login, ...) et les requêtes éventuelles à exécuter.
Chapitre 5<br />
Schéma <strong>XML</strong> canonique pour un<br />
processus ETL<br />
Dans ce chapitre, nous expliquerons comment écrire un schéma <strong>XML</strong> en vue <strong>de</strong> simplifier<br />
le parcours automatique <strong>de</strong> son arborescence <strong>dans</strong> un processus ETL. Avant d’y arriver, nous<br />
donnerons d’abord un petit rappel sur les XSD.<br />
5.1 Motivations<br />
Nous voulons permettre à l’utilisateur <strong>de</strong> faire un mapping entre les schémas source et<br />
<strong><strong>de</strong>s</strong>tination. Il nous faut donc lui présenter ces schémas graphiquement sur l’écran. Notons<br />
également que nous souhaitons une application web la plus légère possible. Tenant compte<br />
du fait que les browsers web actuels sont presque tous capables d’afficher (faire du Parsing)<br />
un fichier <strong>XML</strong>, une idée serait <strong>de</strong> passer tout simplement le schéma XSD au navigateur web<br />
pour affichage.<br />
Afficher un document XSD comme tel pourrait être extrêmement incorfortable pour un utilisateur<br />
dépourvu <strong><strong>de</strong>s</strong> notions soli<strong><strong>de</strong>s</strong> <strong>de</strong> <strong>XML</strong> schema. Notre stratégie est donc <strong>de</strong> créer un<br />
fichier <strong>XML</strong> ne contenant que la structure (<strong>de</strong> l’arbre) représenté <strong>dans</strong> le fichier XSD. Dans<br />
le cas du schéma du listing 2.3 (p. 15), nous voulons quelque chose comme ce qui est <strong>dans</strong> le<br />
listing 5.1.<br />
Listing 5.1 – Visualisation <strong>de</strong> la structure définie <strong>dans</strong> le listing 2.3<br />
<br />
< personslist ><br />
<br />
< firstname /><br />
< middlename /><br />
< lastname /><br />
<br />
<br />
De cette manière l’utilisateur voit directement et <strong>de</strong> façon plus claire l’imbrication et la<br />
séquence <strong><strong>de</strong>s</strong> éléments. Chaque élément porte les attributs éventuels définis <strong>dans</strong> le fichier<br />
XSD.<br />
La difficulté c’est <strong>de</strong> pouvoir parcourir automatiquement tout schéma <strong>XML</strong> d’une source ou<br />
28
CHAPITRE 5. SCHÉMA <strong>XML</strong> CANONIQUE POUR UN PROCESSUS ETL 29<br />
<strong>de</strong> la <strong><strong>de</strong>s</strong>tination en vue d’extraire non pas l’arborescence du schéma XSD comme telle mais<br />
celle du type <strong>de</strong> document qu’il définit. Arrêtons-nous un instant sur cette problématique et<br />
regardons <strong>dans</strong> la section suivante, d’où proviendrait le problème.<br />
5.2 Difficulté d’extraire une structure définie <strong>dans</strong> un schéma<br />
Un schéma XSD étant un fichier <strong>XML</strong>, on peut l’écrire <strong>de</strong> plusieurs manières. A chaque<br />
présentation du schéma, correspond une arborescence différente mais l’arbre défini lui-même<br />
gar<strong>de</strong> la même structure. Le <strong>XML</strong> schema du listing 2.3 (p. 2.3) par exemple, pourrait encore<br />
s’écrire comme <strong>dans</strong> le listing 5.2.<br />
Listing 5.2 – Autre façon d’écrire le schéma du listing 2.3<br />
<br />
<br />
< xs:schema xmlns:xs =" http: // www .w3.org /2001/ <strong>XML</strong>Schema "><br />
< xs:element name =" personslist "><br />
< xs:complexType ><br />
< xs:element name =" person " type =" personType "/><br />
<br />
<br />
< xs:complexType name =" personType "><br />
< xs:element name =" firstname " type =" xs:string "/><br />
< xs:element name =" middlename " type =" xs:string "/><br />
< xs:element name =" lastname " type =" xs:string " use =" require "/><br />
< xs:attribute name =" birthdate " type =" xs:date "/><br />
<br />
<br />
Dans le co<strong>de</strong> du listing 5.2, l’élément person est déclaré directement à l’intérieur <strong>de</strong> la<br />
définition <strong>de</strong> l’élément personslist. Le fait <strong>de</strong> déclarer person avec un attribut type=”personType”<br />
permet <strong>de</strong> donner sa définition à l’extérieur (<strong>dans</strong> un xs :complexType). Remarquez que ce<br />
même schéma peut encore s’écrire comme <strong>dans</strong> le listing 5.3.<br />
Listing 5.3 – Encore une autre manière d’écrire le schéma du listing 2.3<br />
<br />
<br />
< xs:schema xmlns:xs =" http: // www .w3.org /2001/ <strong>XML</strong>Schema "><br />
< xs:element name =" personslist "><br />
< xs:complexType ><br />
< xs:element name =" person "><br />
< xs:complexType ><br />
< xs:element name =" firstname " type =" xs:string "/><br />
< xs:element name =" middlename " type =" xs:string "/><br />
< xs:element name =" lastname " type =" xs:string " use =" require "/><br />
< xs:attribute name =" birthdate " type =" xs:date "/><br />
<br />
<br />
<br />
<br />
CHAPITRE 5. SCHÉMA <strong>XML</strong> CANONIQUE POUR UN PROCESSUS ETL 30<br />
Dans la métho<strong>de</strong> du listing 5.3, les éléments fils sont toujours définis à l’intérieur <strong>de</strong> la<br />
déclaration <strong>de</strong> l’élément père. Si nous <strong>de</strong>vrions <strong><strong>de</strong>s</strong>siner les arbres <strong><strong>de</strong>s</strong> schémas <strong><strong>de</strong>s</strong> listings<br />
2.3, 5.2 et 5.3, nous verrions sans doute que les branches ont <strong><strong>de</strong>s</strong> structures différentes. Et<br />
pourtant, ils définissent exactement le même type <strong>de</strong> document.<br />
En parcourant l’arborescence du schéma pour extraire le type <strong>de</strong> document qui y est défini, on<br />
se rend compte que la définition <strong><strong>de</strong>s</strong> éléments fils peut être <strong>dans</strong> les sous-arbres <strong><strong>de</strong>s</strong>cendants<br />
<strong>de</strong> la branche courante ou carrément <strong>dans</strong> une autre branche (<strong>de</strong> l’arbre du schéma). D’où la<br />
difficulté <strong>de</strong> trouver la définition <strong><strong>de</strong>s</strong> éléments fils et <strong><strong>de</strong>s</strong> attributs éventuels <strong>dans</strong> un parcours<br />
automatique.<br />
Une question qui nous revient à l’esprit est <strong>de</strong> savoir si toutes ces métho<strong><strong>de</strong>s</strong> d’écriture <strong><strong>de</strong>s</strong><br />
schémas sont adaptées pour les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong>. Si <strong>dans</strong> un entrepôt <strong>de</strong> <strong>données</strong> (<strong>XML</strong>)<br />
on évite la répétition inutile <strong><strong>de</strong>s</strong> informations, pourquoi ne pas avoir la même exigence <strong>dans</strong><br />
la définition <strong><strong>de</strong>s</strong> schémas ?<br />
5.3 Eviter les redondances <strong>dans</strong> les schémas<br />
Comme nous venons <strong>de</strong> le voir au paragraphe 5.2, un schéma peut s’écrire <strong>de</strong> plusieurs<br />
metho<strong><strong>de</strong>s</strong>. Malheureusement, il arrive que <strong>dans</strong> certains cas, on trouve <strong><strong>de</strong>s</strong> parties entières <strong>de</strong><br />
co<strong>de</strong> qui se répètent.<br />
Considérons le schéma du listing 2.3, si nous voulons définir une liste <strong>de</strong> personnes subdivisée<br />
en une sous-liste <strong>de</strong> femmes et une sous-liste d’hommes, la métho<strong>de</strong> utilisée <strong>dans</strong> le listing 5.3<br />
risque <strong>de</strong> produire <strong><strong>de</strong>s</strong> redondances parce que chacune <strong><strong>de</strong>s</strong> <strong>de</strong>ux sous-listes pourra contenir la<br />
définition <strong><strong>de</strong>s</strong> mêmes informations définissant les i<strong>de</strong>ntités d’une personne (firstname,name,<br />
...). Ce qui donnerait le co<strong>de</strong> du listing 5.4, par exemple.<br />
Listing 5.4 – Illustration <strong><strong>de</strong>s</strong> redondances <strong>dans</strong> un XSD<br />
<br />
<br />
< xs:schema xmlns:xs =" http: // www .w3.org /2001/ <strong>XML</strong>Schema "><br />
< xs:element name =" personslist "><br />
< xs:complexType ><br />
<br />
< xs:element name =" menlist "><br />
< xs:complexType ><br />
< xs:element name =" man "><br />
< xs:complexType ><br />
< xs:element name =" firstname " type =" xs:string "/><br />
< xs:element name =" middlename " type =" xs:string "/><br />
< xs:element name =" lastname " type =" xs:string " use =" require "/><br />
< xs:attribute name =" birthdate " type =" xs:date "/><br />
<br />
<br />
<br />
<br />
<br />
< xs:element name =" womenlist "><br />
< xs:complexType ><br />
< xs:element name =" woman "><br />
< xs:complexType >
CHAPITRE 5. SCHÉMA <strong>XML</strong> CANONIQUE POUR UN PROCESSUS ETL 31<br />
< xs:element name =" firstname " type =" xs:string "/><br />
< xs:element name =" middlename " type =" xs:string "/><br />
< xs:element name =" lastname " type =" xs:string " use =" require "/><br />
< xs:attribute name =" birthdate " type =" xs:date "/><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Le schéma du listing 5.4 est plus lourd à manipuler. On voit que les éléments man et<br />
woman sont <strong>de</strong> même type mais la manière dont ils sont définis agrandit inutilement l’arbre<br />
du schéma.<br />
Dans un entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong>, on peut faire face à <strong><strong>de</strong>s</strong> schémas relativement grands. Il<br />
faut donc éviter <strong><strong>de</strong>s</strong> répétions inutiles pour ne pas perdre trop <strong>de</strong> temps <strong>dans</strong> le traitement <strong>de</strong><br />
XSD. Nous savons aussi qu’une erreur sur le traitement <strong>de</strong> schéma peut avoir <strong><strong>de</strong>s</strong> conséquences<br />
sur :<br />
– l’interface utilisateur : l’interface permettant <strong>de</strong> faire le mapping entre le schéma source<br />
et <strong><strong>de</strong>s</strong>tination<br />
– l’extraction <strong><strong>de</strong>s</strong> <strong>données</strong> à la source et<br />
– le chargement <strong>de</strong> <strong>données</strong> à la <strong><strong>de</strong>s</strong>tination.<br />
Il nous faut donc proposer quelques règles claires permettant d’écrire un XSD <strong>de</strong> façon plus<br />
appropriée au processus ETL et aux <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> <strong>XML</strong>. Voyons d’abord, en général,<br />
comment écrire un XSD.<br />
5.4 Règles génerales d’écriture d’un XSD<br />
Dans cette section, nous survolons quelques règles d’écriture d’un XSD. Nous ne reprenons<br />
que les points importants dont le rappel nous semble indispensable à la bonne compréhension<br />
<strong><strong>de</strong>s</strong> règles d’écriture d’un schéma canonique. Le lecteur trouvera plus d’informations <strong>dans</strong><br />
[4, 15].<br />
Notons d’abord que l’élément spécial schema () est la racine (Root Element) <strong>de</strong><br />
l’arbre XSD. Pour définir les éléments et/ou les attributs on procè<strong>de</strong> <strong>de</strong> la manière suivante.<br />
– La définition d’un attribut se fait en spécifiant son nom <strong>dans</strong> l’attribut name <strong>de</strong> l’élément<br />
attribute ().<br />
– La définition d’un élément se fait en spécifiant son nom <strong>dans</strong> l’attribut name <strong>de</strong> l’élément<br />
element ().<br />
On distingue <strong>de</strong>ux types d’éléments : le type simple et le type complexe.<br />
5.4.1 Un élément <strong>de</strong> type simple<br />
Un élément <strong>de</strong> type simple ne peut contenir ni autre élément, ni attribut. Il ne peut<br />
contenir que du texte.<br />
L’élément firstname défini <strong>dans</strong> le listing 2.3 (p. 15) par exemple, est <strong>de</strong> type simple :<br />
<br />
De manière générale, on définit un élément <strong>de</strong> type simple comme suit.
CHAPITRE 5. SCHÉMA <strong>XML</strong> CANONIQUE POUR UN PROCESSUS ETL 32<br />
<br />
où elemname est le nom <strong>de</strong> l’élément que l’on veut définir et elemtype un type simple. Parmi<br />
les types simples, on peut citer :<br />
xs : string une chaîne <strong>de</strong> caractères<br />
xs : <strong>de</strong>cimal une valeur numérique signée ou non signée composée <strong>de</strong> 18 chiffres tout au plus<br />
xs : integer une valeur entière<br />
xs : boolean une valeur booléenne qui peut être true (vrai) ou false (faux). Les valeurs 1 et<br />
0 indiquent respectivement true et false.<br />
xs : date la date qui doit s’enco<strong>de</strong>r au format AAAA-MM-JJ où AAAA est l’année, MM le<br />
mois et JJ le jour du mois.<br />
xs : time l’heure au format HH : MM : SS où HH, MM et SS désignent respectivement<br />
l’heure, les minutes et les secon<strong><strong>de</strong>s</strong>.<br />
5.4.2 Un élément <strong>de</strong> type complexe<br />
Un élément <strong>de</strong> type complexe peut contenir d’autres éléments et/ou <strong><strong>de</strong>s</strong> attributs. Il y<br />
<strong>de</strong>ux façons <strong>de</strong> définir un élément <strong>de</strong> type complexe :<br />
1. en définissant les éléments fils et les attributs éventuels à l’intérieur <strong>de</strong> la définition <strong>de</strong><br />
l’élément <strong>de</strong> type complexe ;<br />
2. en définissant les éléments fils et les attributs éventuels à l’extérieur.<br />
5.4.2.1 Définitions <strong><strong>de</strong>s</strong> fils à l’intérieur<br />
La définition <strong><strong>de</strong>s</strong> éléments <strong><strong>de</strong>s</strong>cendants à l’intérieur se fait <strong>de</strong> la manière suivante<br />
<br />
<br />
<br />
<br />
<br />
Les éléments man et woman du listing 5.4 (p.30) par exemple, sont définis selon cette métho<strong>de</strong>.<br />
5.4.2.2 Définitions <strong><strong>de</strong>s</strong> fils à l’extérieur<br />
Dans cette métho<strong>de</strong>, on définit un type complexe qui contiendra les fils et les attributs<br />
éventuels. Les éléments <strong>de</strong> type complexe correspondants sont définis en précisant le nom <strong>de</strong><br />
ce type <strong>dans</strong> l’attribut spécial type. On aura donc les co<strong><strong>de</strong>s</strong> suivants <strong>dans</strong> le fichier XSD.<br />
<br />
<br />
<br />
<br />
où elemname est le nom <strong>de</strong> l’elément <strong>de</strong> type complexe que l’on définit et complexType-<br />
Name, le nom du type complexe. Le listing 5.5 montre un exemple <strong>de</strong> définition utilisant<br />
cette métho<strong>de</strong>.
CHAPITRE 5. SCHÉMA <strong>XML</strong> CANONIQUE POUR UN PROCESSUS ETL 33<br />
Listing 5.5 – Exemple <strong>de</strong> définition d’un élément <strong>de</strong> type complexe<br />
< xs:element name =" man " type =" personType "/><br />
< xs:complexType name =" personType "><br />
< xs:element name =" firstname " type =" xs:string "/><br />
< xs:element name =" middlename " type =" xs:string "/><br />
< xs:element name =" lastname " type =" xs:string " use =" require "/><br />
< xs:attribute name =" birthdate " type =" xs:date "/><br />
<br />
5.5 Règles canoniques<br />
Dans cette section, nous présentons quelques règles permettant d’écrire un schéma XSD<br />
canonique <strong>dans</strong> le cadre d’un processus ETL. Comme nous venons <strong>de</strong> le voir précé<strong>de</strong>mment,<br />
la définition d’un élément <strong>de</strong> type complexe peut avoir un impact important sur le nombre<br />
<strong>de</strong> noeuds <strong>de</strong> l’arbre du schéma. Il nous faut établir quelques règles permettant <strong>de</strong> définir ce<br />
type d’éléments sans augmenter inutilement le contenu du fichier XSD. Le schéma obtenu<br />
doit également respecter les normes du W3C.<br />
Les règles proposées <strong>dans</strong> le cadre <strong>de</strong> ce travail sont les suivantes :<br />
– Seul l’élément racine ne peut être défini comme fils direct <strong>de</strong> l’élément schema ().<br />
– Tout autre élément ne peut être défini que <strong>dans</strong> un type complexe.<br />
– Le nom d’un type complexe ne peut en aucun cas avoir pour préfixe, celui défini <strong>dans</strong><br />
l’espace <strong>de</strong> nom 1 suivi du caractère ” :”.<br />
– Un élément complexe est toujours défini comme au paragraphe 5.4.2.2 (p.32).<br />
– Les éléments <strong>de</strong> type complexe qui ont <strong><strong>de</strong>s</strong> définitions i<strong>de</strong>ntiques doivent se déclarer<br />
comme étant <strong>de</strong> même type complexe.<br />
En appliquant ces règles, on évite <strong>de</strong> gonfler le co<strong>de</strong> inutilement comme <strong>dans</strong> le listing 5.4.<br />
L’élement man et woman sont <strong>de</strong> même type. Il faut définir le type complexe une seule fois.<br />
Le listing 5.6 montre un exemple <strong>de</strong> schéma canonique éliminant les redondances du listing<br />
5.4.<br />
Listing 5.6 – Exemple d’un schéma canonique<br />
<br />
<br />
< xs:schema xmlns:xs =" http: // www .w3.org /2001/ <strong>XML</strong>Schema "><br />
< xs:element name =" personslist " type =" personslistType "/><br />
< xs:complexType name =" personslistType "><br />
< xs:element name =" menlist " type =" menlistType "/><br />
< xs:element name =" womenlist " type =" womenlistType "/><br />
<br />
< xs:complexType name =" menlistType "><br />
< xs:element name =" man " type =" personType "/><br />
<br />
< xs:complexType name =" womenlistType "><br />
< xs:element name =" woman " type =" personType "/><br />
<br />
1 voir [4, 10, 15]
CHAPITRE 5. SCHÉMA <strong>XML</strong> CANONIQUE POUR UN PROCESSUS ETL 34<br />
< xs:complexType name =" personType "><br />
< xs:element name =" firstname " type =" xs:string "/><br />
< xs:element name =" middlename " type =" xs:string "/><br />
< xs:element name =" lastname " type =" xs:string " use =" require "/><br />
< xs:attribute name =" birthdate " type =" xs:date "/><br />
<br />
<br />
Un schéma canonique est plus compact et plus facile à parcourir. On peut à présent trouver<br />
une stratégie <strong>de</strong> parcourir systématiquement tout schéma canonique <strong>de</strong> la source ou <strong>de</strong> la<br />
<strong><strong>de</strong>s</strong>tination pour extraire facilement la structure qui y est définie.<br />
5.6 Comment parcourir un schéma canonique<br />
Le point clé du parcours d’un schéma canonique XSD consiste à tester le type <strong>de</strong> l’élément<br />
défini :<br />
– Si c’est un attribut, alors terminer pour cette branche,<br />
– Si c’est un élément <strong>de</strong> type prédéfini <strong>dans</strong> le langage XSD (type Simple), alors on a fini<br />
pour cette branche,<br />
– Sinon,<br />
– prendre le nom du type (complexe ou défini par l’utilisateur) <strong>dans</strong> l’attribut type,<br />
– chercher la branche qui définit le type dont on vient <strong>de</strong> prendre le nom,<br />
– effectuer un appel récursif sur chacun <strong><strong>de</strong>s</strong> fils éventuels déclarés <strong>dans</strong> ce type,<br />
– terminer et remonter pour passer à l’élément suivant si c’est possible.<br />
Comme nous pouvons le constater <strong>dans</strong> ce parcours et <strong>dans</strong> les algorithmes qui vont suivre,<br />
les techniques <strong>de</strong> récursion sont abondament utilisées <strong>dans</strong> ce travail.
Chapitre 6<br />
Générateur automatique <strong>de</strong> fichier<br />
XSLT<br />
Ce chapitre présente la conception d’un générateur automatique <strong>de</strong> fichier XSLT à partir<br />
<strong><strong>de</strong>s</strong> schémas définis au chapitre 5. C’est ce fichier qui sera appliqué aux <strong>données</strong> <strong>XML</strong> source<br />
pour extraire et transformer les informations.<br />
Nous savons que les langages les plus utilisés pour la transformation <strong><strong>de</strong>s</strong> documents <strong>XML</strong><br />
sont XQuery et XSLT. Mais pourquoi a-t-on choisi XSLT et pas XQuery ? Pour répondre à<br />
cette question, voyons d’abord un petit rappel sur chacun <strong>de</strong> ces langages.<br />
6.1 XPath<br />
XPath est un langage utilisé pour naviguer entre les éléments et les attributs <strong>dans</strong> un document<br />
<strong>XML</strong> [15]. Dans la table 6.1, nous reprenons quelques expressions XPath couramment<br />
utilisées.<br />
Expression Description<br />
/ sélectionne <strong>de</strong>puis la racine<br />
// sélectionne les noeuds du document, qui correspon<strong>de</strong>nt à la sélection.<br />
. sélectionne le noeud courant<br />
@ sélectionne les attributs.<br />
6.2 XQuery<br />
Tab. 6.1 – Qeulques expressions XPath<br />
XQuery est un langage d’interrogation <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>XML</strong>. En d’autres termes, c’est un<br />
langage permettant d’écrire les requêtes sur les documents <strong>XML</strong> comme on le fait avec SQL<br />
sur les bases <strong>de</strong> <strong>données</strong> relationnelles.<br />
XQuery utilise les expressions XPath pour accé<strong>de</strong>r aux noeuds du document. Dans cette section,<br />
nous voulons tout simplement donner un aperçu général du langage XQuery. Le lecteur<br />
35
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 36<br />
trouvera plus d’informations sur http://www.w3schools.com/xquery. Les fonctions les plus<br />
élémentaires en XQuery sont celles d’ouverture <strong>de</strong> document et les expressions FLWOR 1 [7].<br />
6.2.1 Ouverture <strong><strong>de</strong>s</strong> fichiers<br />
L’ouverture <strong><strong>de</strong>s</strong> documents en XQuery se fait en utilisant la fonction spéciale doc. Pour<br />
ouvrir un fichier nommé personslist.xml, par exemple, on écrira<br />
doc("personslist.xml")<br />
6.2.2 Expressions FLWOR<br />
Les expressions FLWOR sont les plus simples en XQuery :<br />
For : permet <strong>de</strong> sélectionner les éléments,<br />
Let : permet <strong>de</strong> déclarer une variable et <strong>de</strong> lui attribuer une valeur,<br />
Where : permet, comme en SQL, <strong>de</strong> spécifier les conditions à satisfaire,<br />
Or<strong>de</strong>red By : permet <strong>de</strong> préciser l’ordre à suivre <strong>dans</strong> le tri.<br />
6.3 XSLT<br />
XSLT est essentiellement utilisé pour la transformation <strong><strong>de</strong>s</strong> documents <strong>XML</strong>. Il définit ses<br />
opérations selon la représentation en arbre <strong><strong>de</strong>s</strong> documents <strong>XML</strong> [5] et utilise les expressions<br />
XPath pour accé<strong>de</strong>r aux noeuds.<br />
Dans ce paragraphe, nous survolons quelques fonctions <strong>de</strong> base les plus utilisées en XSLT. Le<br />
lecteur pourrait approfondir ses connaissances en consultant [5, 15].<br />
6.3.1 Déclaration d’un document XSLT<br />
Comme nous l’avons dit précé<strong>de</strong>mment, un document XSLT est un document <strong>XML</strong>. Pour<br />
déclarer un document XSLT, il faut que l’élément racine soit<br />
ou<br />
<br />
En ajoutant les attributs utiles, nous obtenons<br />
<br />
ou<br />
<br />
6.3.2 Quelques notions <strong>de</strong> base<br />
Ci-après, nous présentons quelques concepts XSLT en vue <strong>de</strong> donner au lecteur ”novice”une<br />
idée générale lui permettant <strong>de</strong> comprendre la suite <strong>de</strong> ce travail.<br />
template contient les règles à appliquer lorsqu’on rencontre un noeud précis. Pour définir<br />
un template, on utilise l’élément<br />
<br />
dont l’attribut match permet <strong>de</strong> préciser le noeud ciblé.<br />
1 Voir le paragraphe 6.2.2
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 37<br />
value-of permet d’extraire la valeur du noeud sélectionné. On utilise l’élement<br />
<br />
dont l’attribut select précise ce qu’il faut sélectionner.<br />
if permet <strong>de</strong> tester une condition. On fait usage <strong>de</strong> l’élément<br />
<br />
dont l’attribut test indique l’expression à tester.<br />
apply-templates permet d’appliquer un template à l’élément courant ou aux noeuds <strong><strong>de</strong>s</strong>cendants.<br />
L’élement utilisé est<br />
<br />
6.4 Pourquoi XSLT et pas XQuery ?<br />
Nous avons préféré d’utiliser XSLT <strong>dans</strong> notre ETL pour les raisons suivantes.<br />
– XSLT utilise la synthaxe <strong>XML</strong>. C’est un document bien formé. Il est donc facilement<br />
extensible.<br />
– Historiquement, XQuery a été conçu pour être un langage <strong>de</strong> requêtes alors que XSLT<br />
est fait pour les transformations. La transformation est sans doute, la partie la plus<br />
difficile <strong>dans</strong> un processus ETL.<br />
– XSLT s’adapte facilement aux systèmes fonctionnant en pipeline [6].<br />
– La version 1.0 <strong>de</strong> XSLT est une recommandation W3C <strong>de</strong>puis 1999 et la 2.0 vient d’être<br />
recommandée en janvier 2007 alors que XQuery 1.0 n’est recommandée qu’en janvier<br />
2007 2 .<br />
– XSLT permet <strong>de</strong> parcourir tout le document source alors XQuery ne vise que certaines<br />
<strong>de</strong> ses parties .<br />
– Le concept <strong>de</strong> template présent <strong>dans</strong> XSLT n’existe pas <strong>dans</strong> XQuery [6]. les ”templates”facilitent<br />
l’écriture <strong><strong>de</strong>s</strong> règles <strong>de</strong> transformation.<br />
– XSLT 2.0 inclut le formatage <strong><strong>de</strong>s</strong> nombres, dates et heures [6]. Ainsi, on pourrait par<br />
exemple, convertir le nombre 1127 en 1.127,00. Chose qu’on ne pourrait pas faire avec<br />
XQuery du moins pour le moment.<br />
– Les 2 langages sont basés sur les expressions XPath.<br />
Fondamentalement, il n’y a pas <strong><strong>de</strong>s</strong> gran<strong><strong>de</strong>s</strong> différences entre les <strong>de</strong>ux langages mais sur le<br />
plan fonctionnel, XSLT 2.0 offre plus <strong>de</strong> possibilité que XQuery [6]. Actuellement, on admet<br />
aussi que le XSLT est plus adapté pour la manipulation <strong><strong>de</strong>s</strong> documents.<br />
Nous choisissons donc XSLT parce que tant à la source qu’à la <strong><strong>de</strong>s</strong>tination, nous avons affaire<br />
avec <strong><strong>de</strong>s</strong> documents <strong>XML</strong>. Le choix <strong>de</strong> XQuery se fera :<br />
– <strong>dans</strong> le traitement <strong><strong>de</strong>s</strong> schémas en vue <strong>de</strong> créer une interface où l’utilisateur pourrait<br />
choisir ses correspondances (Mapping Interface) et<br />
– <strong>dans</strong> l’extraction <strong>de</strong> la structure définie par le schéma XSD en vue <strong>de</strong> la montrer à<br />
l’utilisateur.<br />
Ce choix s’explique aussi par le fait que XQuery s’incorpore plus facilement <strong>dans</strong> les langages<br />
<strong>de</strong> programmation comme le PHP.<br />
2 voir http://fr.wikipedia.org/wiki/XQuery
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 38<br />
6.5 Comment générer un fichier XSLT automatiquement<br />
Pour générer un fichier XSLT automatiquement, la stratégie consiste à<br />
– ouvrir un fichier en écriture et y mettre les entêtes XSLT,<br />
– parcourir l’interface <strong><strong>de</strong>s</strong> correspondances (Mapping Interface) et à chaque type <strong>de</strong> correspondance,<br />
écrire le co<strong>de</strong> XSLT adéquat <strong>dans</strong> le fichier,<br />
– fermer le fichier XSLT.<br />
Dans notre implémentation dont le co<strong>de</strong> PHP se trouve en annexe, ces tâches sont effectuées<br />
<strong>dans</strong> la fonction extractTransform. Ci-après, nous présentons une brève explication en<br />
métalangage pour gar<strong>de</strong>r la conception suffisamment indépendante du langage <strong>de</strong> programmation<br />
utilisé. Tous ces algorithmes propoés sont le résultat <strong>de</strong> notre propre conception.<br />
6.5.1 Programme principal<br />
Le co<strong>de</strong> du programme principal produisant le fichier XSLT se trouve <strong>dans</strong> le listing 6.1.<br />
Dans ce co<strong>de</strong> :<br />
outfilexsl est le nom du fichier XSLT à créer,<br />
filexsl est le <strong><strong>de</strong>s</strong>cripteur du fichier XSLT ouvert,<br />
fopen la primitive permettant d’ouvrir un fichier,<br />
fclose la primitive <strong>de</strong> fermeture du fichier ouvert.<br />
Rappelons que ces <strong>de</strong>ux primitives existent <strong>dans</strong> la plupart <strong><strong>de</strong>s</strong> langages <strong>de</strong> programmation<br />
et que l’ouverture en écriture d’un fichier qui n’existe pas aura pour conséquence, la création<br />
d’un nouveau fichier portant ce nom.<br />
Listing 6.1 – La fonction qui génère le fichier XSLT<br />
function extractTransform ( nbelem )<br />
{<br />
outfilexsl :=" name of the output XSLT file ";<br />
filexsl := fopen ( outfilexsl ,"w"); // open file for writing<br />
fwrite ( filexsl ," \ n");<br />
// write the <strong>XML</strong> <strong>de</strong>claration in the output file<br />
fwrite ( filexsl ," < xsl : transform<br />
xmlns : xsl =\" http :// www .w3.org /1999/ XSL / Transform \"<br />
version =\"1.0\" >\n >") ;<br />
// write the XSLT <strong>de</strong>claration in the output file<br />
fwrite ( filexsl ," < xsl : output method =\" xml \"<br />
encoding =\" ISO -8859 -1\"/ >\ n");<br />
// The output method of the XSLT file is <strong>XML</strong><br />
" generate the content of the XSLT file here !";<br />
// process " nbelem " elements / attributes <strong>de</strong>fined<br />
// in the source XSD<br />
fwrite ( filexsl ," \n");<br />
// close the " xslt : transform " tag<br />
fclose ( filexsl )<br />
// close the output file<br />
}
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 39<br />
6.5.2 Co<strong>de</strong> XSLT selon la transformation <strong>de</strong>mandée<br />
Dans ce paragraphe, nous présentons une façon <strong>de</strong> générer le co<strong>de</strong> XSLT selon le type <strong>de</strong><br />
transformation choisie par l’utilisateur. Nous signalons tout <strong>de</strong> suite que <strong>dans</strong> le prototype<br />
que nous avons développé, nous n’avons couvert que quelques configurations <strong><strong>de</strong>s</strong> transformations.<br />
Notre objectif étant <strong>de</strong> montrer tout simplement la faisabilité <strong>de</strong> générer un XSLT<br />
automatiquement. Pour un ETL à mettre en production, il faut essayer <strong>de</strong> couvrir au mieux<br />
les types <strong><strong>de</strong>s</strong> conversions possibles.<br />
Nous avons implémenté les cas <strong><strong>de</strong>s</strong> transformations suivantes.<br />
– Transformation d’un élément en un autre élément.<br />
– Transformation <strong><strong>de</strong>s</strong> attributs (que l’élément lui-même soit transformé ou pas).<br />
– Transformation <strong><strong>de</strong>s</strong> éléments <strong><strong>de</strong>s</strong>cendants.<br />
Dans le co<strong>de</strong> du listing 6.2, on utilise, notamment, les variables suivantes.<br />
elsrc est le nom <strong>de</strong> l’élément source à transformer éventuellement,<br />
eldst est le nom <strong>de</strong> l’élément <strong><strong>de</strong>s</strong>tination correspondant à la transformation,<br />
attribsrc est le nom <strong>de</strong> l’attribut qu’on veut transformer,<br />
attribdst est le nom <strong>de</strong> l’attribut/élément en quoi se transforme attribsrc,<br />
elsrclst est la liste <strong><strong>de</strong>s</strong> noms <strong><strong>de</strong>s</strong> éléments définis à la source,<br />
eldstlst est la liste <strong><strong>de</strong>s</strong> noms <strong><strong>de</strong>s</strong> éléments définis à la <strong><strong>de</strong>s</strong>tination.<br />
Listing 6.2 – Production du co<strong>de</strong> XSLT selon le type <strong>de</strong> transformation choisie<br />
while (" elsrclst is not empty ")<br />
{<br />
elsrc :=" the next elem in elsrclst ";<br />
eldst :=" corresponding elem in eldstlst ";<br />
fwrite ( filexsl ," < xsl : template match =\" elsrc \" >\n");<br />
// one founds an element called elsrc . What to do?<br />
if (" eldst is not empty ") then<br />
{<br />
fwrite ( filexsl ," < eldst >") ;<br />
// open the tag of the correspoding element<br />
}<br />
" Generate XSLT co<strong>de</strong> for translating attributes of elsrc , if nee<strong>de</strong>d ";<br />
// we have to check wether attributes should be transformed<br />
// even if the elemenent itself is not taken .<br />
if (" eldst is not empty ") then<br />
{<br />
fwrite ( filexsl ," < xsl : apply - templates / >\n");<br />
// apply template of children<br />
fwrite ( filexsl ," ") ;<br />
// close the tag of the <strong><strong>de</strong>s</strong>tination element .<br />
}<br />
else // there is no direct corresponding element<br />
{<br />
fwrite ( filexsl ," < xsl :if test =\" child ::*\" >\ n");<br />
// Test whether the current element has any children<br />
fwrite ( filexsl ," < xsl : apply - templates / >\n");<br />
// apply template of children
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 40<br />
fwrite ( filexsl ," \n");<br />
}<br />
fwrite ( filexsl ," \n");<br />
" remove elsrc from elsrclst ";<br />
// elsrc is processed<br />
}<br />
6.5.3 Transformation <strong><strong>de</strong>s</strong> attributs <strong>de</strong> l’élément courant<br />
Dans cette section nous proposons une stratégie permettant <strong>de</strong> créer le co<strong>de</strong> XSLT pour<br />
transformer les attributs <strong>de</strong> l’élément courant. Dans notre prototype, nous avons couvert les<br />
cas où :<br />
– l’attribut se transforme en un attribut <strong>de</strong> l’élément correspondant au père <strong>dans</strong> la<br />
transformation,<br />
– l’attribut se transforme en élément.<br />
Dans le co<strong>de</strong> du listing 6.3 (p.40) :<br />
attribsrclst est la liste <strong><strong>de</strong>s</strong> attributs <strong>de</strong> l’élément courant <strong>de</strong> la source.<br />
Listing 6.3 – Production du co<strong>de</strong> XSLT pour transformer les attributs <strong>de</strong> l’élément courant<br />
attribsrclst =" list of attributes of elsrc ";<br />
while ( attribsrclst is not empty )<br />
{<br />
// one must process all attributes<br />
attribsrc :=" the next attribute in attribsrclst ";<br />
attribdst :=" corresponding elem or attribute in eldstlst ";<br />
if( attribdst is an attribute of eldst ) then<br />
{<br />
fwrite ( filexsl ," < xsl : attribute name =\" attribdst \" >\n");<br />
// create the attribute<br />
fwrite ( filexsl ," < xsl : value -of select =\" @attribsrc \"/ >\ n");<br />
// take the value of the attribute<br />
fwrite ( filexsl ," \n");<br />
// close creation of attribute<br />
}<br />
else<br />
if( attribdst is an element ) then<br />
{<br />
fwrite ( filexsl ," < attribdst >\n");<br />
fwrite ( filexsl ," < xsl : value -of select =\" @attribsrc \"/ >\ n");<br />
fwrite ( filexsl ," \n");<br />
}<br />
" remove attribsrc from attribsrclst ";<br />
}<br />
6.5.4 Comment trouver l’élément ou l’attribut correspondant ?<br />
Avant d’envisager toute transformation, il faut d’abord trouver ce qui correspond à l’attribut<br />
ou à l’élément que l’on veut transformer. La résolution <strong>de</strong> ce problème est fortement<br />
lié au langage <strong>de</strong> programmation utilisé et à l’interface <strong><strong>de</strong>s</strong> correspondances implémentée.
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 41<br />
Fig. 6.1 – Interface <strong><strong>de</strong>s</strong> correspondances<br />
Dans notre prototype, l’interface <strong>de</strong> la figure 6.1 montre un formulaire <strong>dans</strong> lequel on peut<br />
sélectionner un correspondant pour chaque élément ou attribut source.<br />
Ce formulaire peut être recupéré sous forme <strong>de</strong> tableau à <strong>de</strong>ux colonnes ou sous forme <strong>de</strong> 2<br />
vecteurs <strong>de</strong> même dimension. Il suffit alors <strong>de</strong> parcourir la colonne source et regar<strong>de</strong>r à chaque<br />
fois s’il y a un correspondant à la <strong><strong>de</strong>s</strong>tination.<br />
6.6 Autres opérations possibles<br />
Comme nous venons <strong>de</strong> le voir, nous n’avons implémenté qu’un nombre d’opérations relativement<br />
limité <strong>dans</strong> le prototype pour illustrer la faisabilité d’une génération automatique d’un<br />
fichier XSLT. Dans un environnement <strong>de</strong> production réel, il serait souhaitable d’implémenter<br />
certaines opérations plus compliquées comme celles que nous citons ci-après (liste non ex-
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 42<br />
haustive).<br />
6.6.1 Opérateur <strong>de</strong> fusion<br />
L’opérateur <strong>de</strong> fusion permettra à l’ETL <strong>de</strong> fusionner <strong>de</strong>ux éléments suite à la <strong>de</strong>man<strong>de</strong><br />
<strong>de</strong> l’utilisateur. Rappelons qu’ici l’utilisateur n’est plus censé écrire la moindre ligne <strong>de</strong> co<strong>de</strong> !<br />
Par exemple, si l’entrée est la suivante,<br />
Shele<br />
Tsheke<br />
la fusion donnerait :<br />
ou encore<br />
Tsheke Shele<br />
Shele Tsheke<br />
6.6.2 Opérateur <strong>de</strong> séparation<br />
C’est l’inverse <strong>de</strong> la fusion définie au paragraphe 6.6.1. Si nous mettons à l’entrée<br />
Shele Tsheke<br />
la séparation donnerait :<br />
Shele<br />
Tsheke<br />
6.6.3 Opérateur <strong>de</strong> transformation d’un élément en attribut<br />
C’est plus ou moins l’inverse <strong>de</strong> ce que nous avons implémenté <strong>dans</strong> le prototype. Ici, un<br />
élément donné <strong>de</strong>viendrait un attribut d’un autre élément. Considérons un cas où on aurait<br />
les éléments suivants,<br />
Shele<br />
Tsheke<br />
la transformation donnerait :<br />
Tsheke<br />
6.6.4 Opérateur <strong>de</strong> vérification <strong>de</strong> compatibilité<br />
Cet opérateur est fondamental <strong>dans</strong> un processus ETL. En effet, n’importe quel élément ou<br />
attribut ne peut se transformer en n’importe quel autre élément ou attribut. Il faut s’assurer<br />
<strong>de</strong> la compatibilité <strong><strong>de</strong>s</strong> types pour éviter d’avoir un document non vali<strong>de</strong> à la <strong><strong>de</strong>s</strong>tination.<br />
En particulier, on ne <strong>de</strong>vrait pas arriver à une situation où on puisse mettre le nom d’une<br />
personne à l’endroit prévu pour la date <strong>de</strong> naissance.<br />
6.6.5 Opérateurs arithmétiques<br />
Ces opérateurs <strong>de</strong> base (+,-,/,*) <strong>de</strong>vraient permettre d’effectuer quelques opérations sur<br />
les valeurs numériques au cours d’un processus ETL.
CHAPITRE 6. GÉNÉRATEUR AUTOMATIQUE DE FICHIER XSLT 43<br />
6.6.6 Opérateur <strong>de</strong> manipulation <strong><strong>de</strong>s</strong> instructions <strong>de</strong> traitement<br />
Cet opérateur <strong>de</strong>vrait dire ce qu’il faut faire quand on a affaire à une instruction <strong>de</strong><br />
traitement.<br />
6.6.7 Opérateurs d’exécution paralèlle d’un processus ETL<br />
Ces opérateurs <strong>de</strong>vraient permettre le parallélisme <strong>dans</strong> un processus ETL tel que nous<br />
l’avons abordé au paragraphe 4.1. On pourrait ainsi étudier la possibilité d’une exécution sur<br />
les GRIDs ou sur <strong><strong>de</strong>s</strong> systèmes distribués.
Chapitre 7<br />
Réalisation <strong>de</strong> l’ETL<br />
Ce chapitre montre une façon <strong>de</strong> formaliser et <strong>de</strong> rassembler les fonctions et les concepts<br />
présentés <strong>dans</strong> les chapitres précé<strong>de</strong>nts en vue <strong>de</strong> réaliser un outil ETL réellement fonctionnel.<br />
Nous montrerons en particulier une manière dont on pourrait se servir du fichier XSLT généré<br />
au chapitre 6 pour Extraire, Transformer et Charger (Load) les <strong>données</strong> <strong>dans</strong> l’entrepôt.<br />
Dans le souci <strong>de</strong> permettre au programmeur d’utiliser la méthodologie et le langage <strong>de</strong> programmation<br />
<strong>de</strong> son choix,<br />
– nous présenterons d’abord les algorithmes les plus importants en métalangage et<br />
– nous donnerons par la suite, une explication générale <strong>de</strong> la manière dont on a développé<br />
notre prototype ETL.<br />
7.1 Quelques algorithmes du processus ETL <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>XML</strong><br />
Dans cette section, nous proposons quelques fonctions qui nous semblent indispensables ou<br />
du moins importantes <strong>dans</strong> le développement d’un outil ETL <strong>de</strong> <strong>données</strong> <strong>XML</strong>. Le Développeur<br />
pourra apporter les adapations nécessaires à la métho<strong>de</strong> et/ou au langage <strong>de</strong> programmation<br />
qu’il compte utiliser. Précisons tout <strong>de</strong> même que l’absence <strong>de</strong> référence <strong>dans</strong> cettte section<br />
s’explique par le fait que les algorithmes proposés sont le fruit <strong>de</strong> notre propre conception.<br />
7.1.1 Vérifier si un type est prédéfini en XSD<br />
Comme nous l’avons vu au paragraphe 5.4.1 (p.31), le nom d’un type prédéfini commence<br />
par “xs :”. Le fait d’avoir ce préfixe 1 signifie qu’on est en présence d’un type simple et<br />
prédéfini. Nous formalisons notre raisonnement <strong>dans</strong> le listing 7.1.<br />
Listing 7.1 – Algorithme testant si un type est prédéfini<br />
function isSimpleType ( typeName )<br />
{<br />
returnval := false ;<br />
if "’xs:’ is a prefix of typeName " then returnval := true ;<br />
return returnval ;<br />
}<br />
1 On pourrait, éventuellement, considérer le prefixe ”xsd”<br />
44
CHAPITRE 7. RÉALISATION DE L’ETL 45<br />
7.1.2 Vérifier si un tag <strong>de</strong> XSD définit un élément<br />
Comme nous l’avons vu au chapitre 5 (p. 28), la définition d’un élément se fait avec le tag<br />
spécial xs : element (parfois on utilise xsd : element). Il suffit donc <strong>de</strong> vérifier si on a affaire<br />
avec ce tag pour savoir si on définit un élément. C’est ce que nous faisons <strong>dans</strong> l’algorithme<br />
du listing 7.2.<br />
Listing 7.2 – Algorithme testant si un tag XSD définit un élément<br />
function isElement ( tagName )<br />
{<br />
returnval := false ;<br />
if " tagName is ’xs: element ’" then returnval := true ;<br />
return returnval ;<br />
}<br />
7.1.3 Vérifier si un tag <strong>de</strong> XSD définit un attribut<br />
En suivant un raisonnement analogue á celui du paragraphe 7.1.2, nous obtenons l’algorithme<br />
du listing 7.3.<br />
Listing 7.3 – Algorithme testant si un tag XSD définit un attribut<br />
function isAttribute ( tagName )<br />
{<br />
returnval := false ;<br />
if " tagName is ’xs: attribute ’" then returnval := true ;<br />
return returnval ;<br />
}<br />
7.1.4 Extraction du nom d’un élément, attribut ou type défini<br />
Ce paragraphe montre comment extraire le nom <strong>de</strong> l’élément, <strong>de</strong> l’attribut ou du type<br />
complexe défini <strong>dans</strong> le noeud courant <strong>de</strong> l’arbre du schéma XSD. Pour trouver 2 cette information,<br />
il suffit <strong>de</strong> vérifier si le noeud a <strong><strong>de</strong>s</strong> attributs. Si c’est le cas, alors prendre la valeur <strong>de</strong><br />
l’attribut name. Une fonction que nous proposons pour effectuer cette tâche est reprise <strong>dans</strong><br />
le listing 7.4.<br />
Listing 7.4 – Algorithme d’extraction du nom <strong>de</strong> l’élément/attribut/type complexe défini<br />
function elemName ( no<strong>de</strong> )<br />
{<br />
if (" no<strong>de</strong> is not null " and no<strong>de</strong> -> hasAttributes ()) then<br />
{<br />
returnval := no<strong>de</strong> -> getAttribute (" name ");<br />
}<br />
return returnval ;<br />
}<br />
2 Voir le chapitre 5 pour la définition <strong>de</strong> schéma XSD
CHAPITRE 7. RÉALISATION DE L’ETL 46<br />
7.1.5 Extraction du type <strong>de</strong> l’élément ou <strong>de</strong> l’attribut défini<br />
Dans le listing 7.5, nous proposons une fonction permettant d’extraire le type <strong>de</strong> l’élément<br />
ou <strong>de</strong> l’attribut défini <strong>dans</strong> le noeud passé en argument.<br />
Listing 7.5 – Extraction du type <strong>de</strong> l’élément ou attribut défini<br />
function elemType ( no<strong>de</strong> )<br />
{<br />
if (" no<strong>de</strong> is not null " and no<strong>de</strong> -> hasAttributes ()) then<br />
{<br />
returnval := no<strong>de</strong> -> getAttribute (" type ");<br />
}<br />
return returnval ;<br />
}<br />
7.1.6 Traitement d’un élément et <strong>de</strong> ses fils directs<br />
L’algorithme du listing 7.6 traite l’élément défini <strong>dans</strong> le noeud passé en argument et ses<br />
fils éventuels définis <strong>dans</strong> un type complexe. La fonction retourne une liste contenant le nom<br />
<strong>de</strong> l’élément et ceux <strong>de</strong> ses attributs.<br />
Listing 7.6 – Traitement <strong>de</strong> l’élément défini et <strong>de</strong> ses fils<br />
function sonsAndAttributes ( xpath , no<strong>de</strong> )<br />
{<br />
// xpath is a DOMPath .<br />
// no<strong>de</strong> is a no<strong>de</strong> of this DOM tree .<br />
// variables initialisation<br />
tagName := NULL ;<br />
elemName := NULL ;<br />
sonName := NULL ;<br />
attName := NULL ;<br />
elemType := NULL ;<br />
returnval := NULL ;<br />
if( ( no<strong>de</strong> is not NULL ) and ( xpath is not NULL )) then<br />
{<br />
if( isElement (no<strong>de</strong> -> tagName )) then<br />
{<br />
elemName := elemName ( no<strong>de</strong> );<br />
// take the name of the element<br />
returnval []:= elemName ;<br />
// insert the name of element in the table to return<br />
elemType = elemType ( no<strong>de</strong> );<br />
// take the type<br />
if( not ( isSimpleType ( elemType ))) then<br />
{<br />
// complexType<br />
query :="// xs: complexType [ @name =’ elemType ’]/*";<br />
// take all the children of the <strong>de</strong>fined complexType element<br />
xpathquery := xpath -> query ( query );<br />
// run query and return a list of sons ( no<strong><strong>de</strong>s</strong> )
CHAPITRE 7. RÉALISATION DE L’ETL 47<br />
}<br />
}<br />
foreach ( son in xpathquery )<br />
{<br />
sonTagName := son -> tagName ;<br />
//i.e xs: element<br />
sonName = elemName ( son );<br />
if( isElement ( sonTagName )) then<br />
{<br />
// process the child element if nee<strong>de</strong>d<br />
}<br />
else<br />
if( isAttribute ( sonTagName )) then<br />
{<br />
// process the attribute<br />
returnval []:=" elemName /[ @sonName ]";<br />
}<br />
}<br />
}<br />
}<br />
return returnval ;<br />
7.1.7 Chargement <strong><strong>de</strong>s</strong> schémas<br />
Le chargement <strong><strong>de</strong>s</strong> schémas est intimément lié à la méthodologie et au langage <strong>de</strong> programmation<br />
utilisés. Nous invitons le lecteur à consulter la documentation <strong><strong>de</strong>s</strong> outils <strong>de</strong><br />
développement dont il fait usage. Il trouvera néanmoins un exemple PHP <strong>dans</strong> le co<strong>de</strong> source<br />
en annexe.<br />
7.1.8 Extraction <strong><strong>de</strong>s</strong> éléments et attributs définis <strong>dans</strong> un XSD<br />
Une façon d’extraire les éléments et les attributs définis <strong>dans</strong> un schéma XSD consiste à :<br />
– prendre tous les éléments <strong>de</strong> XSD et<br />
– extraire, pour chacun <strong>de</strong> ces éléments, les attributs éventuels.<br />
Nous illustrons cette démarche <strong>dans</strong> le listing 7.7.<br />
Listing 7.7 – Traitement <strong>de</strong> l’élément défini et <strong>de</strong> ses fils<br />
function extractElem ()<br />
{<br />
" initialize xmldoc to the XSD document ";<br />
" initialize xptah to xpath of the document ";<br />
query :="// xs: element [ @name ]";<br />
// all <strong>de</strong>fined elements<br />
xpathquery := xpath -> query ( query );<br />
// run query<br />
elemlist := array ();<br />
// list of elements and attributes<br />
tmplst := array ();<br />
// the name of the current element and its attributes<br />
foreach ( elem in xpathquery )<br />
{
CHAPITRE 7. RÉALISATION DE L’ETL 48<br />
}<br />
tmplst := sonsAndAttributes ( xpath , elem );<br />
elemlist := merge ( elemlist , tmplst );<br />
}<br />
" process elemlist ";<br />
7.1.9 Parsing d’un noeud et <strong>de</strong> ses fils éventuels<br />
La fonction définie <strong>dans</strong> le listing 7.8 permet notamment d’insérer <strong>dans</strong> la visionneuse<br />
(viewer) <strong><strong>de</strong>s</strong> schémas, le sous arbre défini <strong>dans</strong> XSD et <strong><strong>de</strong>s</strong>cendant à partir du noeud courant.<br />
Nous laissons au programmeur la latitu<strong>de</strong> <strong>de</strong> définir le modèle <strong>de</strong> présentation <strong>dans</strong> lequel il<br />
souhaite visualiser la structure <strong>de</strong> document défini. Dans le prototype, nous avons simplement<br />
créé un fichier <strong>XML</strong> que l’on peut visualiser facilement sur un navigateur web.<br />
Listing 7.8 – Parsing d’une branche d’un arbre défini <strong>dans</strong> un XSD<br />
function parseNo<strong>de</strong> (no<strong>de</strong> , xpath )<br />
{<br />
if (( no<strong>de</strong> is not NULL ) and ( xpath is not NULL )) then<br />
{<br />
tagname := no<strong>de</strong> -> tagName ();<br />
if( isElement ( tagName )) then<br />
{<br />
elemType := elemType ( no<strong>de</strong> );<br />
if( isSimpleType ( elemType )) then<br />
{<br />
" insert element in the viewer ";<br />
}<br />
else<br />
{<br />
// an element of complex type .<br />
query :="// xs: complexType [ @name =’ elemType ’]// xs: attribute [ @name<br />
]";<br />
// attributes of the current element<br />
attributes := xpath -> query ( query );<br />
// run query<br />
" insert element and its attributes in the viewer ";<br />
query :="// xs: complexType [ @name =’ elemType ’]// xs: element [ @name ]";<br />
// children elements<br />
elements := xpath -> query ( query );<br />
// list of children elements<br />
foreach ( element in elements )<br />
{<br />
parseNo<strong>de</strong> ( element , xpath );<br />
// recursive call<br />
}<br />
}<br />
}<br />
else<br />
{<br />
// the no<strong>de</strong> doesn ’t <strong>de</strong>fine an element<br />
if(no<strong>de</strong> -> hasChilds ()) then
CHAPITRE 7. RÉALISATION DE L’ETL 49<br />
}<br />
}<br />
}<br />
{<br />
children := no<strong>de</strong> -> childNo<strong><strong>de</strong>s</strong> ;<br />
// list of children no<strong><strong>de</strong>s</strong><br />
foreach ( child in children )<br />
{<br />
parseNo<strong>de</strong> ( child , xpath );<br />
// recursive call<br />
}<br />
}<br />
7.1.10 Parsing <strong>de</strong> la structure définie <strong>dans</strong> un fichier XSD<br />
La fonction définie <strong>dans</strong> le listing 7.9, permet d’extraire la structure <strong>de</strong> document défini<br />
<strong>dans</strong> un fichier XSD. Cette fonction est notamment utilisée pour créer une visionneuse (viewer)<br />
<strong><strong>de</strong>s</strong> schémas sans montrer le fichier XSD comme tel.<br />
Listing 7.9 – Parsing d’une structure définie <strong>dans</strong> un fichier XSD<br />
function parseSchema ()<br />
{<br />
" initialization of the document ";<br />
" initilization of xpath ";<br />
query :="// xs: schema /xs: element [ @name ]";<br />
// root element<br />
xpathquery := xpath -> query ( query );<br />
// run query<br />
if( xpathquery is not NULL ) then<br />
{<br />
" begin creation of viewer ";<br />
rootElem := xpathquery -> item (0) ;<br />
parseNo<strong>de</strong> ( rootElem , xpath );<br />
" end creation of viewer ";<br />
}<br />
}<br />
7.1.11 Création <strong>de</strong> l’interface <strong><strong>de</strong>s</strong> correspondances<br />
L’interface <strong><strong>de</strong>s</strong> correspondances est la fenêtre <strong>dans</strong> laquelle l’utilisateur déterminera les<br />
transformations à effectuer. Nous laissons au programmeur la liberté <strong>de</strong> créer l’interface <strong>de</strong> son<br />
choix. Dans notre prototype, nous générons un formulaire illustré à la figure 6.1. La fonction<br />
extractElem définie <strong>dans</strong> le listing 7.7 peut ai<strong>de</strong>r à obtenir la liste <strong><strong>de</strong>s</strong> éléments et <strong><strong>de</strong>s</strong> attributs<br />
définis <strong>dans</strong> les schémas XSD source et <strong><strong>de</strong>s</strong>tination.<br />
7.1.12 Compilation d’un processus ETL<br />
Dans ce paragraphe, nous illustrons une manière <strong>de</strong> rassembler (compiler) les différentes<br />
fonctions définies précé<strong>de</strong>mment pour réaliser un processus ETL. C’est ici où nous faisons<br />
usage du fichier XSLT généré au chapitre 6 (p. 35).
CHAPITRE 7. RÉALISATION DE L’ETL 50<br />
La connexion à la source <strong>de</strong> <strong>données</strong> se fera en fonction <strong>de</strong> son SGBD et <strong><strong>de</strong>s</strong> types <strong>de</strong><br />
connexions autorisées. Les <strong>données</strong> extraites et transformées seront chargées <strong>dans</strong> l’entrepôt<br />
<strong>de</strong> <strong>données</strong> <strong>XML</strong> selon les règles prévues pour le chargement.<br />
Listing 7.10 – Compilation d’un processus ETL<br />
function initETL ()<br />
{<br />
if (" There is no XSLT for the transformation ")<br />
{<br />
" Load source and <strong><strong>de</strong>s</strong>tination schemas ";<br />
" Run extractelem for XSD source ";<br />
" Run extractelem for XSD <strong><strong>de</strong>s</strong>tination ";<br />
" Run parseSchema for XSD source ";<br />
" Run parseSchema for XSD <strong><strong>de</strong>s</strong>tination ";<br />
" Create a mapping interface ";<br />
" Generate the XSLT file at request ";<br />
// run extractTransform<br />
}<br />
" Apply the XSLT file on the source data ";<br />
// data are Extracted and Transformed<br />
" Load Transformed Data to the <strong>XML</strong> Warehouse ";<br />
// data Extracted , Transformed and Loa<strong>de</strong>d<br />
}<br />
7.2 Prototype ETL développé<br />
Dans le prototype que nous avons développé, nous avons utilisé un serveur web apache et<br />
le langage <strong>de</strong> programmation PHP5. Quant à la méthologie <strong>de</strong> programmation, nous avons<br />
opté pour une approche orienté objet.<br />
Nous avons développé une application web pour permettre aux ayants droit <strong>de</strong> l’utiliser à<br />
distance sans avoir à installer une quelconque application cliente mais d’utiliser tout simplement<br />
un navigateur web (Internet Explorer, Fire Fox,...). Pour le chargement <strong>de</strong> <strong>données</strong>,<br />
nous nous sommes limité à stocker le fichier résultat <strong>dans</strong> un répertoire donné.<br />
Nous reprenons un exemple d’application au chapitre 8 (p.51) pour illustrer le fonctionnement<br />
du prototype développé. Le lecteur intéressé trouvera le co<strong>de</strong> source <strong>dans</strong> les annexes.
Chapitre 8<br />
Exemple d’application<br />
Dans ce chapitre, nous présentons un exemple d’application du protype ETL que nous<br />
avons développé. Il y aura beaucoup d’images <strong>de</strong> capture d’écran parce qu’il s’agit d’une<br />
application web dynamique.<br />
De manière générale, l’application consiste en<br />
– un chargement <strong>de</strong> schéma XSD source<br />
– un chargement <strong>de</strong> schéma XSD <strong><strong>de</strong>s</strong>tination (entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong>)<br />
– un fichier <strong>XML</strong> <strong>de</strong> <strong>données</strong> source<br />
– une génération automatique d’un fichier XSLT<br />
– extraction, transformation et chargement (Load) <strong>de</strong> la source vers la <strong><strong>de</strong>s</strong>tination.<br />
Dans ce prototype, le chargement à l’entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> se fait en stockant le fichier<br />
<strong>XML</strong> produit par l’ETL <strong>dans</strong> un répertoire précis (output).<br />
8.1 Chargement <strong><strong>de</strong>s</strong> fichiers <strong>dans</strong> l’ETL<br />
La page d’accueil montrée à la figure 8.1 offre la possibilité <strong>de</strong> charger les schémas source<br />
et <strong><strong>de</strong>s</strong>tination. Quant au fichier <strong>de</strong> <strong>données</strong>, en principe, l’ETL se connecte à la source pour<br />
extraire les <strong>données</strong> mais <strong>dans</strong> ce prototype, nous avons prévu la possibilité d’aller les chercher<br />
<strong>dans</strong> un répertoire donné ou <strong>de</strong> les charger sur l’ETL (à la page d’accueil).<br />
Pour tester l’application, nous procédons <strong>de</strong> la manière suivante.<br />
– Charger le schéma XSD source ( listing 8.1 p. 51).<br />
– Charger le schéma XSD <strong><strong>de</strong>s</strong>tination (listing 2.3 p. 15).<br />
– Les <strong>données</strong> <strong>de</strong> la source sont celles du listing 8.2 (p. 52).<br />
– cliquer sur le bouton Upload Files pour vali<strong>de</strong>r le chargement.<br />
Listing 8.1 – Schema XSD d’une source<br />
<br />
<br />
< xs:schema xmlns:xs =" http: // www .w3.org /2001/ <strong>XML</strong>Schema "><br />
< xs:element name =" listepersonnes " type =" typeListePersonnes "/><br />
< xs:complexType name =" typeListePersonnes "><br />
< xs:element name =" personne " type =" typePersonne "/><br />
<br />
51
CHAPITRE 8. EXEMPLE D’APPLICATION 52<br />
< xs:complexType name =" typePersonne "><br />
< xs:element name =" prenom " type =" xs:string "/><br />
< xs:element name =" nom<strong>de</strong>famille " type =" xs:string " use =" require "/><br />
< xs:element name =" langue " type =" xs:string "/><br />
< xs:attribute name =" datenais " type =" xs:date " use =" require "/><br />
<br />
<br />
Fig. 8.1 – Page d’accueil <strong>de</strong> <strong>XML</strong> ETL<br />
Listing 8.2 – Données <strong>XML</strong> d’une source<br />
<br />
< listepersonnes ><br />
< personne datenais =" 2008 -12 -12 "><br />
Johnny <br />
< nom<strong>de</strong>famille >Tsheke <br />
français <br />
<br />
< personne datenais =" 2009 -06 -12 "><br />
Pierre <br />
< nom<strong>de</strong>famille > Manneback <br />
français <br />
<br />
< personne datenais =" 2004 -10 -08 ">
CHAPITRE 8. EXEMPLE D’APPLICATION 53<br />
Esteban <br />
< nom<strong>de</strong>famille > Zimanyi <br />
français <br />
<br />
<br />
8.2 Visualisation <strong><strong>de</strong>s</strong> schémas chargés<br />
Une fois les fichiers chargés, on arrive à une page permettant <strong>de</strong> visualiser les structures<br />
<strong><strong>de</strong>s</strong> arborescences définies respectivement par le schéma source et le schéma <strong><strong>de</strong>s</strong>tination.<br />
Fig. 8.2 – Visualisation <strong><strong>de</strong>s</strong> arborescences définies <strong>dans</strong> les schémas<br />
Comme le montre la figure 8.2, le ”Mapping Interface”permet <strong>de</strong> choisir les correspondances<br />
<strong>de</strong> la transformation qu’on souhaite effectuer.<br />
8.3 Un choix <strong>de</strong> correspondances<br />
Prenons par exemple un cas <strong>dans</strong> lequel on choisit toutes les informations relatives à<br />
une personne, à l’exception <strong>de</strong> ”langue”. (voir la figure 8.3). Cliquons ensuite sur le bouton<br />
”Transforme”<strong>de</strong> ”Mapping Interface”. L’ETL génère dès lors le co<strong>de</strong> XSLT repris <strong>dans</strong> le<br />
listing 8.3 (p. 53).<br />
Listing 8.3 – XSLT généré suite aux choix du paragraphe 8.3<br />
<br />
< xsl:transform xmlns:xsl =" http: // www .w3.org /1999/ XSL / Transform "<br />
version =" 1.0 "><br />
< xsl:output method =" xml " encoding ="ISO -8859 -1 "/><br />
< xsl:template match =" listepersonnes ">
CHAPITRE 8. EXEMPLE D’APPLICATION 54<br />
< personslist ><br />
<br />
<br />
<br />
< xsl:template match =" personne "><br />
<br />
< xsl:attribute name =" birthdate "><br />
<br />
<br />
<br />
<br />
<br />
< xsl:template match =" prenom "><br />
< firstname ><br />
<br />
<br />
<br />
Fig. 8.3 – Un choix d’une transformation
CHAPITRE 8. EXEMPLE D’APPLICATION 55<br />
< xsl:template match =" nom<strong>de</strong>famille "><br />
< lastname ><br />
<br />
<br />
<br />
< xsl:template match =" langue "><br />
<br />
<br />
<br />
<br />
<br />
Le co<strong>de</strong> XSLT généré automatiquement (voir listing 8.3 p. 53) est ensuite appliqué aux <strong>données</strong><br />
<strong>de</strong> la source (voir listing 8.2 p. 52) pour produire les <strong>données</strong> du listing 8.4 (p. 55) que l’on<br />
charge <strong>dans</strong> l’entrepôt.<br />
Listing 8.4 – Résultat du processus ETL du paragraphe 8.3 sur les <strong>données</strong> du listing 8.2<br />
<br />
< personslist ><br />
<br />
< firstname >Johnny <br />
< lastname >Tsheke <br />
<br />
<br />
< firstname >Pierre <br />
< lastname > Manneback <br />
<br />
<br />
< firstname > Esteban <br />
< lastname > Zimanyi <br />
<br />
<br />
8.4 Un autre choix <strong>de</strong> correspondances<br />
Supposons à présent que l’on souhaite plutôt conserver une liste d’anniversaires <strong>dans</strong><br />
l’entrepôt <strong>de</strong> <strong>données</strong> et que la source soit la même que celle du paragraphe 8.3. Le schéma<br />
<strong>de</strong> <strong><strong>de</strong>s</strong>tination est celui du listing 8.5 (p. 55).<br />
Listing 8.5 – Schéma <strong>de</strong> <strong><strong>de</strong>s</strong>tination du processus ETL du paragraphe 8.4<br />
<br />
<br />
< xs:schema xmlns:xs =" http: // www .w3.org /2001/ <strong>XML</strong>Schema "><br />
< xs:element name =" listeanniv " type =" typeListeAnniv "/><br />
< xs:complexType name =" typeListeAnniv "><br />
< xs:element name =" anniv " type =" typeAnniv "/><br />
<br />
< xs:complexType name =" typeAnniv "><br />
< xs:element name =" dateanniv " type =" xs:date "/><br />
< xs:element name =" nom " type =" xs:string "/>
CHAPITRE 8. EXEMPLE D’APPLICATION 56<br />
<br />
<br />
En choisissant les correspondances comme à la figure 8.4, le système génère le fichier XSLT<br />
du listing 8.6 et transforme les <strong>données</strong> du listing 8.2 (p. 52) en celles qui sont <strong>dans</strong> le listing<br />
B.1. Les <strong>données</strong> extraites et transformées sont ensuite chargées <strong>dans</strong> l’entrepôt <strong>de</strong> <strong>données</strong><br />
<strong>XML</strong>.<br />
Listing 8.6 – XSLT généré suite aux choix du paragraphe 8.4<br />
<br />
< xsl:transform xmlns:xsl =" http: // www .w3.org /1999/ XSL / Transform "<br />
version =" 1.0 "><br />
< xsl:output method =" xml " encoding ="ISO -8859 -1 "/><br />
< xsl:template match =" listepersonnes "><br />
< listeanniv ><br />
<br />
<br />
<br />
< xsl:template match =" personne "><br />
<br />
< dateanniv ><br />
<br />
<br />
<br />
<br />
<br />
< xsl:template match =" prenom "><br />
<br />
<br />
<br />
<br />
< xsl:template match =" nom<strong>de</strong>famille "><br />
<br />
<br />
<br />
<br />
< xsl:template match =" langue "><br />
<br />
<br />
<br />
<br />
<br />
Listing 8.7 – Résultats <strong>de</strong> l’ETL éxécuté au paragraphe 8.4<br />
<br />
< listeanniv ><br />
<br />
< dateanniv >2008 -12 -12 <br />
Tsheke
CHAPITRE 8. EXEMPLE D’APPLICATION 57<br />
<br />
<br />
< dateanniv >2009 -06 -12 <br />
Manneback <br />
<br />
<br />
< dateanniv >2004 -10 -08 <br />
Zimanyi <br />
<br />
<br />
Fig. 8.4 – Un autre choix <strong>de</strong> transformation
Chapitre 9<br />
Conclusions et perspectives<br />
9.1 Conclusions<br />
Dans les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong> <strong>XML</strong>, on acquiert les informations à partir <strong><strong>de</strong>s</strong> sources <strong>de</strong><br />
<strong>données</strong> <strong>XML</strong>. Ces sources sont indépendantes et peuvent avoir chacune un schéma XSD à la<br />
fois différent <strong><strong>de</strong>s</strong> autres et <strong>de</strong> celui <strong>de</strong> l’entrepôt. Les <strong>données</strong> à stocker <strong>dans</strong> l’entrepôt doivent<br />
cependant être vali<strong><strong>de</strong>s</strong> par rapport au schéma <strong>de</strong> l’entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong>.<br />
Pour transférer les informations d’une source vers l’entrepôt, il faut les extraire puis les<br />
transformer pour qu’elles respectent les exigences du schéma <strong>de</strong> <strong><strong>de</strong>s</strong>tination et les charger par<br />
la suite <strong>dans</strong> l’entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong>. C’est ce qu’on appelle communément un processus<br />
ETL (Extract, Transform, Load).<br />
Le but <strong>de</strong> ce travail était <strong>de</strong> définir un processus ETL permettant d’alimenter un entrepôt<br />
<strong>de</strong> <strong>données</strong> <strong>XML</strong> à partir <strong><strong>de</strong>s</strong> sources <strong>de</strong> <strong>données</strong> <strong>XML</strong>. Il était aussi question <strong>de</strong> développer<br />
un prototype d’outil associé.<br />
Nous avons montré qu’une bonne conception d’un processus ETL <strong>de</strong> <strong>données</strong> <strong>XML</strong> pouvait<br />
résoudre, non pas seulement le problème d’approvisionnement <strong><strong>de</strong>s</strong> entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong>,<br />
mais aussi beaucoup d’autres problèmes <strong>de</strong> transformation <strong>de</strong> format <strong>de</strong> <strong>données</strong>. Un petit<br />
rappel sur le langage <strong>XML</strong> a été donné en survol pour rafraichir les mémoires sur les concepts<br />
fondamentaux qu’on allait utiliser par la suite.<br />
Les bases <strong>de</strong> <strong>données</strong> <strong>XML</strong>, les <strong>entrepôts</strong> <strong>de</strong> <strong>données</strong>, les entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> et leurs<br />
fonctionnements ont été revus sans entrer trop en détail. Une petite comparaison entre un<br />
entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong> et un entrepôt <strong>de</strong> <strong>données</strong> a été donnée tout en rappelant que la<br />
frontière entre les <strong>de</strong>ux n’était pas très étanche.<br />
Nous avons regardé par la suite l’évolution du processus ETL tant sur le plan conceptuel<br />
que sur le plan logiciel. Quelques techniques et logiciels ont été parcourus pour donner une<br />
idée générale <strong>de</strong> ce qu’on peut trouver sur le marché.<br />
58
CHAPITRE 9. CONCLUSIONS ET PERSPECTIVES 59<br />
Après un bref rappel sur les schémas <strong>XML</strong> (<strong>XML</strong> schema - XSD), nous avons proposé<br />
quelques règles canoniques permettant d’écrire un fichier XSD plus compact. La préoccupation<br />
était <strong>de</strong> ne pas alourdir inutilement le processus ETL au cours <strong>de</strong> la manipulation <strong><strong>de</strong>s</strong> schémas<br />
source et <strong><strong>de</strong>s</strong>tination.<br />
Sachant que si on a un fichier XSLT, on peut l’appliquer sur la source <strong>XML</strong> pour extraire et<br />
transformer les <strong>données</strong>, nous avons proposé un générateur automatique <strong>de</strong> fichier XSLT. La<br />
création <strong>de</strong> ce fichier se fait en fonction <strong><strong>de</strong>s</strong> schémas XSD source et <strong><strong>de</strong>s</strong>tination. Ce concept<br />
<strong>de</strong> générateur automatique <strong>de</strong> fichier XSLT rend l’ETL utilisable tant <strong>dans</strong> les entrpôts <strong>de</strong><br />
<strong>données</strong> <strong>XML</strong> que <strong>dans</strong> d’autres domaines comme les systèmes d’informations géographiques<br />
(Geographic Information System - GIS).<br />
Dans cet ouvrage, nous avons donné une implémentation quasi complète du noyau <strong>de</strong> l’ETL<br />
que nous avons défini. Les algorithmes ont été proposés en métalangage pour permettre au<br />
programmeur d’utiliser sa méthodologie et son langage <strong>de</strong> programmation favoris.<br />
Les algorithmes proposés ont été testés <strong>dans</strong> le prototype que nous avons développé en<br />
PHP5 sur un serveur apache. Un exemple d’application a d’ailleurs été donné pour montrer<br />
son fonctionnement.<br />
9.2 Perspectives<br />
Nous admettons que par manque <strong>de</strong> temps, nous n’avons pas pu optimiser toutes les fonctions<br />
proposées <strong>dans</strong> le cadre <strong>de</strong> ce travail <strong>de</strong> fin d’étu<strong><strong>de</strong>s</strong>. Les recherches futures éventuelles<br />
pourraient s’orienter vers :<br />
– l’optimisation <strong><strong>de</strong>s</strong> algorithmes ;<br />
– l’implémentation <strong><strong>de</strong>s</strong> opérateurs proposés à la section 6.6 (p. 41) ;<br />
– l’amélioration du générateur <strong>de</strong> fichier XSLT pour prendre en charge <strong><strong>de</strong>s</strong> cas où il y<br />
aurait une très gran<strong>de</strong> différence entre les formes <strong><strong>de</strong>s</strong> arbres source et <strong><strong>de</strong>s</strong>tination ;<br />
– l’étu<strong>de</strong> <strong>de</strong> la possibilité d’insérer du co<strong>de</strong> XQuery <strong>dans</strong> le fichier XSLT généré <strong>dans</strong> le<br />
cadre d’un processus ETL <strong><strong>de</strong>s</strong> <strong>données</strong> <strong>XML</strong> ;<br />
– la conception et l’implémentation d’une interface permettant à l’ETL <strong>de</strong> se connecter à<br />
la plupart <strong><strong>de</strong>s</strong> SGBD capables d’exporter/importer les <strong>données</strong> en <strong>XML</strong> ;<br />
– la conception d’une interface permettant <strong>de</strong> charger les <strong>données</strong> <strong>dans</strong> un entrepôt <strong>de</strong><br />
<strong>données</strong> <strong>XML</strong> <strong>de</strong> manière incrémentale.
Bibliographie<br />
[1] Serge Abiteboul. Cours <strong>de</strong> <strong>XML</strong> et <strong>données</strong> semi-structurées. INRIA, 2005. http:<br />
//www-rocq.inria.fr/ ∼ abitebou/DEA-III.<br />
[2] Serge Abiteboul, Peter Buneman, and Dan Suciu. Data on the Web. From relations to<br />
semistructured data and <strong>XML</strong>. Morgan Kaufmann Publishers, 2000.<br />
[3] Akmal B. Chaudhri, Awais Rachid, and Roberto Zicari. <strong>XML</strong> Data Management : Native<br />
<strong>XML</strong> and <strong>XML</strong> Enabled Database Systems. Addison-Wesley Professional, 2003.<br />
[4] Pierre Gaspart. Cours <strong>de</strong> technologies <strong>XML</strong> -info370. ULB, 2006. http://www.sfp.<br />
ulb.ac.be.<br />
[5] Michael Kay. XSLT. Wrox Press Ltd, second edition, 2001.<br />
[6] Michael Kay. Comparing xslt and xquery. XTech 2005 Conference Proceedings, 2005.<br />
http://www.i<strong>de</strong>alliance.org/proceedings/xtech05.<br />
[7] Michael Kay. Blooming flower - an introduction to the xquery flower expression. Stylus<br />
Studio, 2006. http://www.stylusstudio.com/whitepapers/blooming flower.pdf.<br />
[8] Brian Knight, Allan Mitchell, Darren Green, Douglas Hinson, Kathi Kellenberger, Andy<br />
Leonard, Erik Veerman, Jason Gerard, Haidong Ji, and Mike Murphy. Professional SQL<br />
Server 2005, Integration services. Wiley Publishing, Inc, 2007.<br />
[9] Casey Kochmer and Erica Frandsen. JSP and <strong>XML</strong>, Integrating <strong>XML</strong> and Web services<br />
in your JSP application. Addison-Wesley, 2002.<br />
[10] Pierre Manneback. Cours <strong>de</strong> technologies du web. FPMS, 2006. https://elearning.<br />
stu<strong>de</strong>nt.fpms.ac.be/.<br />
[11] Hiroshi Maruyama, Kent Tamura, and Naohiko Uramoto. <strong>XML</strong> and Java, Developing<br />
Web Applications. Addison-Wesley, 1999.<br />
[12] Brett McLaughlin. Java and <strong>XML</strong>. O’Reilly, second edition, 2001.<br />
[13] Erik T. Ray. Learning <strong>XML</strong>. O’Reilly, 2001.<br />
[14] Arizona State University. Asu data warehouse overview. Arizona State University, 2002.<br />
http://www.asu.edu/data admin/data warehouse-overview.html.<br />
[15] w3cschools. Xml schema tutorial. w3cschools, 2007. http://www.w3cschools.com.<br />
[16] Wikipédia. Extensible 3d. Wikipédia, 2007. http://fr.wikipedia.org/wiki/X3D.<br />
[17] Wikipédia. Extract, transform, load. Wikipédia, 2007. http://en.wikipedia.org/<br />
wiki/Extract, transform, load.<br />
[18] Wikipédia. Xml database. Wikipédia, 2007. http://en.wikipedia.org/wiki/<strong>XML</strong><br />
database.<br />
[19] Pierre Wolper. Cours <strong>de</strong> base <strong>de</strong> <strong>données</strong>. ULG, 2006. http://www.montefiore.ulg.<br />
ac.be/ ∼ pw.<br />
60
Annexe A<br />
Co<strong>de</strong> PHP5 du prototype ETL<br />
développé<br />
A.1 Fichier in<strong>de</strong>x.php<br />
Ce fichier contient entre autre, le formulaire <strong>de</strong> chargement <strong><strong>de</strong>s</strong> schémas.<br />
Listing A.1 – Fichier In<strong>de</strong>x.php<br />
<br />
<br />
<br />
<strong>XML</strong> ETL <strong><strong>de</strong>s</strong>igned by Johnny Tsheke : si.fpms - co<strong>de</strong> .ulb <br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Upload source schema ( xsd file ) <br />
<br />
<br />
<br />
Upload <strong><strong>de</strong>s</strong>tination schema ( xsd file ) <br />
<br />
<br />
<br />
Upload source data ( xml file ) <br />
61
ANNEXE A. CODE PHP5 DU PROTOTYPE ETL DÉVELOPPÉ 62<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<strong>XML</strong> ETL -- author : Johnny Tsheke Shele , si.fpms - co<strong>de</strong> .ulb <br />
<br />
< frameset rows ="10% ,*" ><br />
<br />
< frameset cols ="30% ,* ,30%" ><br />
<br />
<br />
<br />
<br />
Pas moyen d’ afficher les frames<br />
<br />
<br />
<br />
<br />
ANNEXE A. CODE PHP5 DU PROTOTYPE ETL DÉVELOPPÉ 63<br />
A.2 Fichier viewsrc.php<br />
Ce fichier permet <strong>de</strong> visualiser l’arbre <strong>de</strong> la structure définie <strong>dans</strong> le schéma source.<br />
setxsdsrc (src );<br />
trans -> setxsddst (dst );<br />
trans -> loadschemas ();<br />
trans -> extractelem (" SRC ");<br />
trans -> extractelem (" DST ");<br />
srctree =" input /". strtok ( basename (trans -> xsdsrc ) ,".") .". xml ";<br />
dsttree =" input /". strtok ( basename (trans -> xsddst ) ,".") .". xml ";<br />
trans -> parseSchema (srctree ," SRC ");<br />
trans -> parseSchema (dsttree ," DST ");<br />
trans = null ;<br />
hea<strong>de</strong>r (’ Location : input / srcxsd .xml ’);<br />
?><br />
A.3 Fichier viewdst.php<br />
Ce fichier permet <strong>de</strong> visualiser l’arbre <strong>de</strong> la structure définie <strong>dans</strong> le schéma <strong><strong>de</strong>s</strong>tination<br />
(entrepôt <strong>de</strong> <strong>données</strong> <strong>XML</strong>).<br />
Listing A.3 – Fichier viewdst.php<br />
setxsdsrc (src );<br />
trans -> setxsddst (dst );<br />
trans -> loadschemas ();<br />
trans -> extractelem (" SRC ");<br />
trans -> extractelem (" DST ");<br />
srctree =" input /". strtok ( basename (trans -> xsdsrc ) ,".") .". xml ";<br />
dsttree =" input /". strtok ( basename (trans -> xsddst ) ,".") .". xml ";<br />
trans -> parseSchema (srctree ," SRC ");<br />
trans -> parseSchema (dsttree ," DST ");<br />
trans = null ;<br />
hea<strong>de</strong>r (’ Location : input / dstxsd .xml ’);<br />
?>
ANNEXE A. CODE PHP5 DU PROTOTYPE ETL DÉVELOPPÉ 64<br />
A.4 Fichier mapping.php<br />
Ce fichier permet <strong>de</strong> visualiser l’interface <strong><strong>de</strong>s</strong> correspondances.<br />
Listing A.4 – Fichier mapping.php<br />
initEtl (_POST [ nbsrcelem ]);<br />
?>
Annexe B<br />
Co<strong>de</strong> source <strong>de</strong> la classe<br />
XmlTransform<br />
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 66<br />
{<br />
if (! is_null (newname ))<br />
{<br />
this -> xsdsrc =newname ;<br />
}<br />
// return this -> xsdsrc ;<br />
}// fin fonction setxsdsrc<br />
//---------------------------------------------------------/<br />
// assignation du nom <strong>de</strong> fichier xsd <strong><strong>de</strong>s</strong>tination /<br />
//-------------------------------------------------------- /<br />
function setxsddst (newname = NULL )<br />
{<br />
if (! is_null (newname ))<br />
{<br />
this -> xsddst =newname ;<br />
}<br />
}// fin fonction setxsddst<br />
//--------------------------------------------------------------/<br />
// La fonction suivante arrete la transformation en cas d’ erreur /<br />
//--------------------------------------------------------------/<br />
function stopetl (message = NULL )<br />
{<br />
print (" < font color =\" red \" size =\"3\" >") ;<br />
print (" Error ... ") ;<br />
if (! is_null (message ))<br />
{<br />
print (message );<br />
}<br />
else {<br />
print (" No message received ");<br />
}<br />
print (" ETL stoped !!! ") ;<br />
print (" ") ;<br />
exit (1) ;<br />
} // fin stopetl<br />
//-------------------------------------------------------------/<br />
// La fonction suivante test si un type passe en argument /<br />
// est simple cad built -in. Dans ce cas le systeme retourne true /<br />
// rapelons que les types built -in sont prefxes par xs: ou xsd : /<br />
// exemple : xs: string xs: integer .... /<br />
//-------------------------------------------------------------/<br />
function isSimpleType (typeName = null )<br />
{<br />
returnval = false ;<br />
slength = strlen (typeName );<br />
if(slength >3)<br />
{// le nom du type doit doit avoir plus <strong>de</strong> 3 caracteres<br />
if (( substr (typeName ,0 ,3) == "xs :") ||( substr (typeName ,0 ,4) == "<br />
xsd :") )<br />
{
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 67<br />
returnval = true ;<br />
}<br />
}<br />
return returnval ;<br />
}<br />
//--------------------------------------------------------------/<br />
// la fonction suivante test une entree xs ou xsd pour voir si /<br />
// on <strong>de</strong>finit un element /<br />
//--------------------------------------------------------------/<br />
function isElement (tagName = null )<br />
{<br />
returnval = false ;<br />
slength = strlen (tagName );<br />
if(slength >9)<br />
{// le nom du tag doit avoir plus <strong>de</strong> 9 caracteres<br />
if (( substr (tagName ,0 ,10) == "xs: element ") ||( substr (tagName ,0 ,11)<br />
== " xsd : element "))<br />
{<br />
returnval = true ;<br />
}<br />
}<br />
return returnval ;<br />
}<br />
//--------------------------------------------------------------/<br />
// la fonction suivante test une entree xs ou xsd pour voir si /<br />
// on <strong>de</strong>finit un attribut /<br />
//--------------------------------------------------------------/<br />
function isAttribute (tagName = null )<br />
{<br />
returnval = false ;<br />
slength = strlen (tagName );<br />
if(slength >11)<br />
{// le nom du tag doit avoir plus <strong>de</strong> 11 caracteres<br />
if (( substr (tagName ,0 ,12) == "xs: attribute ") ||( substr (tagName<br />
,0 ,13) == " xsd : attribute "))<br />
{<br />
returnval = true ;<br />
}<br />
}<br />
return returnval ;<br />
}<br />
//-------------------------------------------------------------/<br />
// la fonction suivante return le nom <strong>de</strong> l’element , attribut /<br />
// ou complexType <strong>de</strong>finie par le noeud (<strong>de</strong> xs: schema ) passe en /<br />
// argument /<br />
//-------------------------------------------------------------/<br />
function elemName (no<strong>de</strong> = null )<br />
{returnval = null ;<br />
nm =" name ";<br />
if (!( is_null (no<strong>de</strong> )))<br />
{if(no<strong>de</strong> -> hasAttributes ())
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 68<br />
{<br />
returnval =no<strong>de</strong> -> getAttribute (nm );<br />
}<br />
}<br />
return returnval ;<br />
}// fin <strong>de</strong> la fonction elemName<br />
//-------------------------------------------------------------/<br />
// La fonction suivante returne le type d’un element <strong>de</strong>finie /<br />
// <strong>dans</strong> le noeud (<strong>de</strong> xs: schema ) passe en argument /<br />
//-------------------------------------------------------------/<br />
function elemType (no<strong>de</strong> = null )<br />
{returnval = null ;<br />
tp =" type ";<br />
if (!( is_null (no<strong>de</strong> )))<br />
{if(no<strong>de</strong> -> hasAttributes ())<br />
{<br />
returnval =no<strong>de</strong> -> getAttribute (tp );<br />
}<br />
}<br />
return returnval ;<br />
}// fin <strong>de</strong> la fonction elemType<br />
//-------------------------------------------------------------/<br />
// La fonction suivante retourne la liste <strong><strong>de</strong>s</strong> noms <strong><strong>de</strong>s</strong> tags /<br />
// fils directs ( attributs ) du noeud passe en argument ( ainsi /<br />
// que les attributs /<br />
//-------------------------------------------------------------/<br />
function sonsAndAttributes (xpath =null ,no<strong>de</strong> = null )<br />
{ //xpath est le DOMpath d’ou vient le noeud no<strong>de</strong><br />
tagName = null ;// le nom du noeud<br />
elemName = null ;// le nom <strong>de</strong> l’ element <strong>de</strong>fini par le tag<br />
sonName = null ; // le noeud d’un element fils si possible<br />
attName = null ; // le nom d’un attribut si possible<br />
elemType = null ;// type <strong>de</strong> l’ element<br />
returnval = null ; // tableau array <strong><strong>de</strong>s</strong> noms a renvoyer<br />
if (!(( is_null (no<strong>de</strong> )) ||( is_null (xpath ))))<br />
{// si un noeud et un chemin sont passes en argument<br />
if(this -> isElement (no<strong>de</strong> -> tagName ))<br />
{<br />
elemName =this -> elemName (no<strong>de</strong> );<br />
returnval []= elemName ; // nom <strong>de</strong> l’ element<br />
elemType =this -> elemType (no<strong>de</strong> );<br />
if (!(this -> isSimpleType (elemType )))<br />
{// si pas type simple alors type complexe .<br />
// on cherche les fils <strong>dans</strong> la <strong>de</strong>finition du type<br />
// selectionner la <strong>de</strong>fintion du schema <strong>de</strong><br />
//l’ element xs: complexType<br />
query ="// xs: complexType [ @name =’elemType ’]/*";
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 69<br />
xpathquery =xpath -> query (query );<br />
// extraction <strong><strong>de</strong>s</strong> element fils et attributs<br />
foreach (xpathquery as son )<br />
{<br />
sonTagName = son -> tagName ;<br />
sonName =this -> elemName (son );<br />
{<br />
else<br />
{<br />
}<br />
}<br />
if(this -> isElement (sonTagName ))<br />
// possibilite <strong>de</strong> traiter les elements fils direct<br />
}<br />
if(this -> isAttribute (sonTagName ))<br />
{<br />
returnval []=" elemName /[ @sonName ]";<br />
}<br />
}<br />
}<br />
}<br />
return returnval ;<br />
} // fin <strong>de</strong> la fonction sonsAndAttributes<br />
//-------------------------------------------------------------/<br />
// La fonction suivante charge les schemas src et dst <strong>dans</strong> les /<br />
// document <strong>XML</strong> DOM ( php5 ) en vue <strong>de</strong> les traiter comme <strong>dans</strong> /<br />
// <strong>dans</strong> un parser /<br />
//-------------------------------------------------------------/<br />
function loadschemas ()<br />
{<br />
if (( is_null (this -> xsdsrc )) ||( is_null (this -> xsddst )))<br />
{<br />
this -> stopetl (" source and /or <strong><strong>de</strong>s</strong>tination schema unknown ");<br />
}<br />
if ((! file_exists (this -> xsdsrc )))<br />
{<br />
print (" < font color =\" red \" size =\"3\" > The source schema ".this -><br />
xsdsrc . " does not exists ");<br />
exit (1) ;<br />
}<br />
if ((! file_exists (this -> xsddst )))<br />
{<br />
print (" < font color =\" red \" size =\"3\" > The schema ".this -> xsddst<br />
. " does not exists ");<br />
exit (1) ;<br />
}
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 70<br />
this -> xmlsrcdoc = new DOMDocument ();<br />
this -> xmlsrcdoc -> validateOnParse = true ;<br />
this -> xmldstdoc = new DOMDocument ();<br />
this -> xmldstdoc -> validateOnParse = true ;<br />
// chargement du schema source<br />
if (!this -> xmlsrcdoc -> load (this -> xsdsrc ))<br />
{<br />
this -> stopetl (" cannot load ".this -> xsdsrc );<br />
}<br />
if (!this -> xmldstdoc -> load (this -> xsddst ))<br />
{<br />
this -> stopetl (" cannot load ".this -> xsddst );<br />
}<br />
// creation <strong>de</strong> DOM path<br />
this -> xpathsrc = new DOMXPath (this -> xmlsrcdoc );<br />
this -> xpathdst = new DOMXPath (this -> xmldstdoc );<br />
}// fin loadschemas<br />
//-----------------------------------------------------------------/<br />
// La fonction suivante initialise le document <strong>de</strong> travail<br />
/<br />
//-----------------------------------------------------------------/<br />
function initDoc (srcordst = null )<br />
{<br />
src =" SRC ";<br />
dst =" DST ";<br />
xmldoc = null ;<br />
if (( strcasecmp (srcordst ,src ) !=0) &&( strcasecmp (srcordst ,dst )<br />
!=0) )<br />
{<br />
this -> stopetl (" argument of initDoc must be: SRC or DST ");<br />
}<br />
// si on cherche a extraire les elements <strong>de</strong> la source<br />
if( strcasecmp (srcordst ,src ) ==0)<br />
{<br />
xmldoc =this -> xmlsrcdoc ;<br />
}<br />
else<br />
{// si on cherche a extraire les elements <strong>de</strong> la <strong><strong>de</strong>s</strong>tination<br />
xmldoc =this -> xmldstdoc ;<br />
}<br />
return xmldoc ;<br />
} // fin initDoc<br />
//-----------------------------------------------------------------/
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 71<br />
// La fonction suivante initialise le xpath <strong>de</strong> travail<br />
/<br />
//-----------------------------------------------------------------/<br />
function initXpath (srcordst = null )<br />
{<br />
src =" SRC ";<br />
dst =" DST ";<br />
xpath = null ;<br />
if (( strcasecmp (srcordst ,src ) !=0) &&( strcasecmp (srcordst ,dst )<br />
!=0) )<br />
{<br />
this -> stopetl (" argument of initXpath must be: SRC or DST ");<br />
}<br />
// si on cherche a extraire les elements <strong>de</strong> la source<br />
if( strcasecmp (srcordst ,src ) ==0)<br />
{<br />
xpath =this -> xpathsrc ;// chemin du schema source<br />
}<br />
else<br />
{// si on cherche a extraire les elements <strong>de</strong> la <strong><strong>de</strong>s</strong>tination<br />
xpath =this -> xpathdst ;// chemin du schema <strong><strong>de</strong>s</strong>tination<br />
}<br />
return xpath ;<br />
} // fin initXpath<br />
//------------------------------------------------------------------/<br />
// La fonction suivante extrait les elements ( attribut ) du documents<br />
/<br />
// et les place <strong>dans</strong> un tableau<br />
/<br />
//------------------------------------------------------------------/<br />
function extractelem (srcordst = NULL )<br />
{xmldoc = NULL ;<br />
xmldoc = NULL ;<br />
returnval = array () ;// tableau <strong><strong>de</strong>s</strong> elements / attributs extrait du<br />
document<br />
src =" SRC ";<br />
dst =" DST ";<br />
xsdSchema =" xsd : schema ";// noeud special indiquant un schema xsd<br />
rootNo<strong>de</strong> = NULL ;<br />
xmldoc =this -> initDoc (srcordst ) ;// initialisation document <strong>de</strong><br />
travail<br />
xpath =this -> initXpath (srcordst ) ;// xpath <strong>de</strong> travail<br />
rootNo<strong>de</strong> =xmldoc -> documentElement ;<br />
rootNo<strong>de</strong>Name =rootNo<strong>de</strong> -> tagName ;<br />
sons =rootNo<strong>de</strong> -> childNo<strong><strong>de</strong>s</strong> ;
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 72<br />
// extraire toutes les <strong>de</strong>claration d’ elements<br />
query ="// xs: element [ @name ]";<br />
xpathquery =xpath -> query (query );<br />
nb =xpathquery -> length ;<br />
elemlist = array ();<br />
foreach (xpathquery as elem )<br />
{<br />
tmlst =this -> sonsAndAttributes (xpath ,elem );<br />
elemlist = array_merge (elemlist ,tmlst );<br />
}<br />
if( strcasecmp (srcordst ,src ) ==0)<br />
{// si on cherche a extraire les elements <strong>de</strong> la source<br />
this -> srcelemlist =elemlist ;<br />
}<br />
else<br />
{// si on cherche a extraire les elements <strong>de</strong> la <strong><strong>de</strong>s</strong>tination<br />
this -> dstelemlist =elemlist ;<br />
}<br />
}// fin <strong>de</strong> la fonction extractelem<br />
//-------------------------------------------------------/<br />
// La fonction suivante fait le parsing du noeud /<br />
// on fait un appel recursif s’il y a <strong><strong>de</strong>s</strong> fils eventuels /<br />
//-------------------------------------------------------/<br />
function parseNo<strong>de</strong> (file =null ,no<strong>de</strong> =null ,prefix =null ,xpath = null )<br />
{<br />
// prefix est le prefixe <strong>de</strong> xml schema . ex: xsd , xs<br />
newtag = null ; // tag a cree <strong>dans</strong> le fichier<br />
if (( is_null (no<strong>de</strong> )) ||( is_null (file )) ||( is_null (prefix )) ||(<br />
is_null (xpath )))<br />
{<br />
this -> stop (" Argument incorrects a la fonction parseNo<strong>de</strong> ");<br />
}<br />
tagName =no<strong>de</strong> -> tagName ;<br />
if(this -> isElement (tagName ))<br />
{// si c’est noeud element xs: element<br />
elemName =this -> elemName (no<strong>de</strong> ) ;// le nom <strong>de</strong> l’ element<br />
newtag =elemName ;// le nom du tag . on doit encore trouver<br />
// les attrubutseventuels<br />
elemType =this -> elemType (no<strong>de</strong> );<br />
if(this -> isSimpleType (elemType ))<br />
{// Si un element <strong>de</strong> type simple<br />
fwrite (file ," \n");<br />
}<br />
else {<br />
// si un element <strong>de</strong> type complex<br />
query ="//". prefix .": complexType [ @name =’elemType ’]//". prefix .":
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 73<br />
attribute [ @name ]";<br />
attributes =xpath -> query (query );<br />
// on vient <strong>de</strong> recuperer tous les attributs<br />
attlst = null ;<br />
foreach (attributes as attribute )<br />
{// recuperation <strong>de</strong> la liste <strong><strong>de</strong>s</strong> attributs<br />
atname =this -> elemName (attribute );<br />
attype =this -> elemType (attribute );<br />
attlst =attlst ." ".atname ."=\"". attype ."\"";<br />
}<br />
fwrite (file ," \n");<br />
// on va maintenant recuperer les elements fils<br />
query ="//". prefix .": complexType [ @name =’elemType ’]//". prefix<br />
.": element [ @name ]";<br />
elements =xpath -> query (query );<br />
foreach (elements as element )<br />
{<br />
this -> parseNo<strong>de</strong> (file ,element ,prefix ,xpath );<br />
}<br />
}<br />
fwrite (file ," \n");<br />
}<br />
else<br />
{// si pas un noued element<br />
if(no<strong>de</strong> -> hasChilds ())<br />
{ // Si le noeud a <strong><strong>de</strong>s</strong> fils on fait un appel recursif<br />
// ceci permet <strong>de</strong> couvrir les cas <strong>de</strong> par<br />
exemple<br />
children =no<strong>de</strong> -> childNo<strong><strong>de</strong>s</strong> ;<br />
foreach (children as child )<br />
{<br />
parseNo<strong>de</strong> (file ,child ,prefix ,xpath );<br />
}<br />
}<br />
}<br />
}// fin parseNo<strong>de</strong><br />
//-------------------------------------------------------/<br />
// La fonction suivante cree un fichier xml compose /<br />
// uniquement <strong><strong>de</strong>s</strong> tags et <strong>de</strong> l’ eborescente correspondant /<br />
// au fichier xsd passe en argument /<br />
//-------------------------------------------------------/<br />
function parseSchema (outputfile =null ,srcordst = null )<br />
{<br />
xmldoc = null ;<br />
xpath = null ;<br />
filename = null ;<br />
prefix =" xs :";// prefix xsd<br />
if( is_null (outputfile ))<br />
{
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 74<br />
this -> stop (" Il faut specifier le nom du fichier <strong>de</strong> sortie ");<br />
}<br />
filename =outputfile ;<br />
xmldoc =this -> initDoc (srcordst ) ;// initialisation document<br />
<strong>de</strong> travail<br />
xpath =this -> initXpath (srcordst ) ;// xpath <strong>de</strong> travail<br />
// extraction du prefix<br />
rootNo<strong>de</strong> =xmldoc -> documentElement ;<br />
rootName =rootNo<strong>de</strong> -> tagName ;<br />
prefix = strtok (rootName ,":") ; // prefixe utiliser <strong>dans</strong> le<br />
fichier xsd<br />
query ="//". prefix .": schema /". prefix .": element [ @name ]";<br />
rootNo<strong>de</strong> = null ; // liberation <strong>de</strong> la memoire<br />
xpathquery =xpath -> query (query );<br />
if (( is_null (xpathquery )) ||( xpathquery -> length stop (" Aucun element <strong>de</strong>clar~A <strong>dans</strong> ce fichier xml schema ")<br />
;<br />
}<br />
file = fopen ("filename " ,"w") ;// <strong><strong>de</strong>s</strong>cripteur <strong>de</strong> fichier<br />
fwrite (file ," \ n");<br />
fwrite (file ," parseSchema -->\n");<br />
rootElem =xpathquery -> item (0) ;<br />
// parsing <strong>de</strong> l’ element<br />
this -> parseNo<strong>de</strong> (file ,rootElem ,prefix ,xpath );<br />
fclose (file );<br />
xmldoc = null ;// liberation <strong>de</strong> la memoire<br />
xpath = null ;<br />
} // fin <strong>de</strong> la fonction parseSchema<br />
//--------------------------------------------------------/<br />
// La fonction suivante affiche l’ interface d’ equivalence /<br />
// c’est ici que l’ utilisateur choisi les correspondances /<br />
// <strong><strong>de</strong>s</strong> elements /<br />
// on suppose que les noms <strong><strong>de</strong>s</strong> elemenst / attributs <strong>de</strong> /<br />
// <strong>de</strong> la source et <strong>de</strong> la <strong><strong>de</strong>s</strong>tionation sont <strong>de</strong>ja extraits /<br />
//--------------------------------------------------------/<br />
function mapping (srctree ,dsttree )<br />
{<br />
nbsrcelem = null ; // nombre d’ element / attributs <strong>de</strong>finis <strong>dans</strong> le<br />
schema source<br />
nbdstelem = null ; // nombre d’ element / attributs <strong>de</strong>finis <strong>dans</strong> le<br />
schema <strong><strong>de</strong>s</strong>tination<br />
if (( is_null (this -> srcelemlist )) ||( is_null (this -> dstelemlist )))<br />
{
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 75<br />
this -> stop (" Elements not extratced yet ");<br />
}<br />
else {<br />
nbdstelem = count (this -> dstelemlist );<br />
nbsrcelem = count (this -> srcelemlist );<br />
echo "< form method =\" post \" action =\" mapping . php \" >";<br />
echo "< table cellspacing =3 cellpadding =0 bor<strong>de</strong>r =1 >";<br />
echo "";<br />
echo "< font color =\" green \" > FROM ";<br />
echo "< font color =\" blue \" >TO ";<br />
echo " ";<br />
for (i =0;i dstelemlist [j ]." ";<br />
}<br />
echo " ";<br />
echo " ";<br />
echo " ";<br />
}<br />
echo " ";<br />
echo " ";<br />
echo "< input type =\" hid<strong>de</strong>n \" name =\" nbdstelem \" value =\" nbdstelem<br />
\" >";<br />
echo "< input type =\" hid<strong>de</strong>n \" name =\" nbsrcelem \" value =\" nbsrcelem<br />
\" >";<br />
echo "< input type =\" hid<strong>de</strong>n \" name =\" srctree \" value =\" srctree<br />
\" >";<br />
echo "< input type =\" hid<strong>de</strong>n \" name =\" dsttree \" value =\" dsttree<br />
\" >";<br />
echo "< input type =\" submit \" name =\" submit \" value =\" Transforme<br />
\" >";<br />
echo " ";<br />
}<br />
}// fin <strong>de</strong> la fonction mapping<br />
//--------------------------------------------------------------/<br />
// La fonction suivante effectue l’ extraction et la transformation /<br />
// selon les equivalances choisies par l’ utilisateur <strong>dans</strong> mapping /<br />
//---------------------------------------------------------------/<br />
function extractTransform (datafile ,nbelem =null ,dsttree = null )<br />
{
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 76<br />
mapping = array ();<br />
outfilexsl = null ; // nom du fichier xsl resultant<br />
filexsl = null ;// <strong><strong>de</strong>s</strong>cripteur <strong>de</strong> fichier xsl<br />
//nbelem est le nombre maximum d’ element <strong>de</strong> produire<br />
for (i =0;i load (datafile );<br />
outfilexsl = strtok (dsttree ,".") .". xsl "; // fichier xsl resultant<br />
filexsl = fopen (outfilexsl ,"w"); // ouverture du fichier en<br />
ecriture<br />
// ecriture <strong><strong>de</strong>s</strong> entetes xsl<br />
fwrite (filexsl ," \ n<br />
");<br />
fwrite (filexsl ," < xsl : transform xmlns : xsl =\" http :// www .w3.org<br />
/1999/ XSL / Transform \" version =\"1.0\" >\ n");<br />
fwrite (filexsl ," < xsl : output method =\" xml \" encoding =\" ISO<br />
-8859 -1\"/ >\ n");<br />
// generer le contenu xsl ici<br />
ne =0;<br />
while (ne 0)<br />
{<br />
//s’il y a un element correspondant<br />
fwrite (filexsl ," \n");<br />
}<br />
j =1;<br />
stop = false ;<br />
while (((ne +j)
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 77<br />
// regar<strong>de</strong> s’il faut transformer les attribut <strong>de</strong> l’ element<br />
en cours<br />
// <strong>de</strong> traitement<br />
attribpos = strpos (elsrclst [ne +j ] ,"/") ;<br />
if(attribpos !== false )<br />
{<br />
// si l’ element suivant est un attribut , on regar<strong>de</strong> s’il se<br />
transforme<br />
// ~A un attribut ou un element<br />
ind =ne +j; // indice <strong>de</strong> l’ attribut<br />
start =attribpos +3;<br />
atln = strlen (elsrclst [ind ]) -start -1;// on elenve le<br />
<strong>de</strong>rnier caractere [<br />
attribsrc = substr (elsrclst [ind ],start ,atln );<br />
attribdstpos = strpos (eldstlst [ne +j ] ,"/") ;<br />
if(attribdstpos !== false )<br />
{<br />
start =attribdstpos +3;<br />
atln = strlen (eldstlst [ind ]) -start -1;// on elenve le<br />
<strong>de</strong>rnier caractere [<br />
attribdst = substr (eldstlst [ind ],start ,atln );<br />
if(eldstln >0)<br />
{<br />
// l’ attribut se transforme ~A un attribut<br />
fwrite (filexsl ," < xsl : attribute name =\" attribdst \" >\n");<br />
fwrite (filexsl ," < xsl : value -of select =\" @attribsrc<br />
\"/ >\ n");<br />
fwrite (filexsl ," \n");<br />
}<br />
}<br />
else<br />
{<br />
// l’ attribut se transforme<br />
ind =ne +j;<br />
if (( strlen (eldstlst [ind ])) >0)<br />
{<br />
~A un element<br />
//s’il<br />
}<br />
j ++;<br />
y a effectivement un element correspondant<br />
fwrite (filexsl ," \n");<br />
fwrite (filexsl ," < xsl : value -of select =\" @attribsrc<br />
\"/ >\ n");<br />
fwrite (filexsl ," \n");<br />
}<br />
}<br />
else<br />
{<br />
// l’ element<br />
stop = true ;<br />
}<br />
suivant n’est pas un attribut et on arrete
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 78<br />
}<br />
if(eldstln >0)<br />
{<br />
//s’il y a un element correspondant<br />
fwrite (filexsl ," < xsl : apply - templates / >\n");<br />
fwrite (filexsl ," \n");<br />
}<br />
else<br />
{ //s’il n’y a aucun element correspondant a l’ element en cours<br />
<strong>de</strong> traitement<br />
fwrite (filexsl ," < xsl :if test =\" child ::*\" >\ n");<br />
fwrite (filexsl ," < xsl : apply - templates / >\n");<br />
fwrite (filexsl ," \n");<br />
}<br />
fwrite (filexsl ," \n");<br />
ne =ne +j;<br />
}<br />
// fin contenu xsl<br />
fwrite (filexsl ," \n");<br />
fclose (filexsl );<br />
// on va maintenant applique le fichier xsl sur l’ arbre<br />
outputdata =" output /". strtok ( basename (datafile ) ,".") ." etl . xml ";//<br />
donnees tranformees<br />
// Attention : la partie suivante est specifique a php5<br />
// nouvelle instance du processeur xslt<br />
xslt = new XSLTProcessor ();<br />
// chargement du fichier XSLT<br />
xsl = new DOMDocument ();<br />
xsl -> load (outfilexsl );<br />
// importation <strong>de</strong> xsl<br />
xslt -> importStylesheet (xsl );<br />
// on applique la transformation sur le fichier data<br />
if(xslt -> transformToUri (docdata ,outputdata ))<br />
{<br />
echo "< font color =\" green \"> Data \" ETLed \" successfully ";<br />
//--- AFFICHAGE DES FICHIERS GENERES PAR L’ OUTIL ETL ----/<br />
echo "< center >";<br />
echo " Click on the link for wich you want to see / download the file<br />
";<br />
echo " Source schema tree ";<br />
echo " Destination schema tree ";<br />
echo " XSL generated by the ETL tool ";<br />
echo " Input data file ";<br />
echo " Output data file ( from ETL tool )<br />
";<br />
echo " ";<br />
}
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 79<br />
} // fin <strong>de</strong> la fonction extractTransform<br />
//--------------------------------------------/<br />
// La fonction suivante initialise les operations ETL /<br />
//---------------------------------------------/<br />
// function initEtl (nbdstelem = null )<br />
function initEtl (nbsrcelem = null )<br />
{<br />
?><br />
<br />
<strong>XML</strong> ETL -- author : Johnny Tsheke , si.fpms - co<strong>de</strong> .ulb <br />
<br />
<br />
< font color =" red "> Mapping Interface <br />
<br />
xsddst ) ,".") ." xsd . xml<br />
";<br />
this -> parseSchema (srctree ," SRC ");<br />
this -> srctree =srctree ;<br />
this -> parseSchema (dsttree ," DST ");<br />
this -> dsttree =dsttree ;<br />
//---- fin parseschema ---<br />
this -> mapping (srctree ,dsttree );<br />
}<br />
else<br />
{ // Effectuer l’ extraction et la transformation<br />
// suivi du chargement<br />
dsttree =_POST [ dsttree ]; // arbre <strong>de</strong> <strong><strong>de</strong>s</strong>tination<br />
//this -> extractTransform (" personcd2 . xml ",nbdstelem ,dsttree );<br />
//this -> extractTransform (" personcd2 . xml ",nbsrcelem ,dsttree )<br />
;<br />
this -> extractTransform (" input / srcdata . xml ",nbsrcelem ,
ANNEXE B. CODE SOURCE DE LA CLASSE <strong>XML</strong>TRANSFORM 80<br />
}<br />
dsttree );<br />
}<br />
}// fin <strong>de</strong> la fonction initEtl<br />
//**************************************************<br />
// FIN CLASSE <strong>XML</strong>TRANSFORM *<br />
//**************************************************<br />
trans = new XmlTransform ;// objet <strong>de</strong> transformation<br />
?>