13.07.2013 Views

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 ...

SHOW MORE
SHOW LESS

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 />

?>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!