Découverte de XGQL

Rémi Masson

Cet article vise a démontrer la facilité d'utilisation de XGQL pour intégrer des données provenant de sources hétérogènes. ♪

- Titre : Découverte de XGQL

- Auteur : Rémi Masson

- Parution : 13 juillet 2007

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Qu'est-ce que XGQL ?

- II. Étude de cas

- II-A. Contexte

- II-B. Approche SQL/JAVA/XSLT

- II-C. Réalisation XGQL

- III. Conclusion

- Remerciements

I - Qu'est-ce que XGQL ?

XGQL (XML Generator Query Language) est un langage procédural qui permet selon un formalisme XML de générer/transformer des flux provenant de Web Services, de sources de données XML ou de bases de données relationnelles. Il allie ainsi le meilleur des mondes XML et relationnel en utilisant toutes les fonctionnalités de XPath, de XQuery et du SQL.

Pour bien comprendre toutes les possibilités du XGQL, nous allons réaliser une étude de cas assez simple permettant de comparer deux approches :

1. SQL, JAVA et XSLT ;

2. XGQL.

II - Étude de cas

II-A - Contexte

La société Annu-Artisan gère un annuaire de sites d'artisans et une liste de leurs produits classés par thèmes.

La société Annu-Artisan souhaite proposer un ensemble de sites marchands à thèmes regroupant la production des artisans déjà inscrits dans son annuaire. Comme elle a la capacité de lire et de traiter des flux XML extérieurs, chaque artisan inscrit devra fournir une description de ses produits via un flux XML.

Exemple de flux à fournir

<produit>
<libelle>Marteau</libelle>
<description_courte>Marteau à enfoncer les clous de girofle</description_courte>
<description_longue>Un magnifique marteau à enfoncer les clous de girofle : très utile en cuisine</description_longue>
<images>
<img>http://photo.ortho.free.fr/images/outils/marteau.jpg</img>
<img>http://www.stefatelier.com/catalog/images/marteau.jpg</img>
</images>
<prix>79</prix>
<stock>5</stock>
<delai_livraison>4</delai_livraison>
</produit>

Pour simplifier la gestion, les données concernant chaque produit (ID et thème du produit) restent stockées dans l'annuaire de Annu-Artisan, dans la table ANNU_PRODUCT ; le champ URL contient l'URL à appeler pour récupérer le flux XML de la description du produit.

IDPRODUITS

IDTHEME

URL

3453

1

http://urlArtisan1/monProduit.xml

892

1

http://urlArtisan2/monProduit.xml

4729

2

http://urlArtisan3/monProduit.xml

Toutes ces données doivent ensuite être normalisées, afin de générer les différentes interfaces des multiples sites.

Figure 1 - Présentation du traitement des flux attendus

II-B - Approche SQL/JAVA/XSLT

Un procédé assez simple serait de réaliser quelques servlets agrégatrices des différentes sources de donnés (base de données et web-service).

Figure 2 - Traitement des flux avec SQL/Java/XSLT

Le traitement se fait en quatre étapes.

Étape 1 - connexion à la base

Connexion à la base et récupération des informations en fonction d'un thème précis, avec une requête du type : MAQUERY = « SELECT URL FROM ANNU_PRODUCT WHERE IDTHEME=1 », le champ URL représentant les différentes adresses des flux XML à récupérer, pour établir une cohérence des données.

//Initialisation
ResultSet result = null;
Statement statement = null;
Connection connect = null;
// Connexion à la base

try {
Class.forName(className);
connect = java.sql.DriverManager.getConnection(url, name, password);
connect.setAutoCommit(false);

} catch (Exception e) {
// gestion de l'exception
}

// exécution de la requête
try {
statement = connect.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
result = statement.executeQuery(MAQUERY);
} catch (Exception e) {
// gestion de l'exception
}

// fermeture de la connexion à la base de données
try {
connect.close();
} catch (Exception e) {
// gestion de l'exception
}

Étape 2 - Récupération des informations

Récupération des informations du flux XML en fonction des données intégrées dans la base

URL url = new URL(urlFluxXml);
conn = url.openConnection();
conn.connect();

data = new DataInputStream(new BufferedInputStream(
conn.getInputStream()));

while ((line = data.readLine()) != null) {
buf.append(line);
}

data.close();

Étape 3 - Génération du XML

L'agrégation peut se faire avec un simple objet StringBuffer.

myXMLResult.append(xmlResult);

Étape 4 - Normalisation du XML par un traitement XSLT

Cette feuille XSLT aura pour seul but de supprimer les informations superflues dans le flux XML en fonction des demandes. Par exemple, pour une page de présentation rapide des produits, on voudra uniquement les champs 'libellés' et 'description courte'.

II-C - Réalisation XGQL

En utilisant l'API XGQL, il est possible de générer en quelques lignes de script le XML normalisé souhaité.

Figure 3 - Traitement des flux avec XGQL

Il est possible faire le traitement très rapidement de la façon suivante :

<?xml version="1.0" encoding="UTF-8"?>

<xgql:root xmlns:xgql="http://www.symeria.com/xgql/">
<products>

<!-- définition de la requête -->
<xgql:var name="select"> SELECT URL FROM ANNU_PRODUCT WHERE IDTHEME=1</xgql:var>

<!-- exécution de la requête -->
<xgql:execute name="select">

<!-- iteration sur les différents résultats -->
<xgql:row>
<xgql:var name="productUrl">
<xgql:column name="url" wrap="false"/>
</xgql:var>

<!-- récupération des différents flux XML, via protocole HTTP -->
<xgql:var name="product">
<xgql:datasource>$productUrl</xgql:datasource>
</xgql:var>

<!-- normalisation du flux XML -->
<produit>
<xgql:process>document{$product}/produit/libelle</xgql:process>
<xgql:process>document{$product}/produit/description_courte</xgql:process>
</produit>
</xgql:row>

</xgql:execute>

</products>
</xgql:root>

Ce script génère le résultat suivant :

<products>
<produit>
<libelle>Marteau</libelle>
<description_courte>Marteau à enfoncer les clous de girofle</description_courte>
</produit>
</products>

Sur cet exemple de script XGQL, trois instructions sont particulièrement importantes (et bien pratiques aussi !) :

<xgql:execute name="select">
<xgql:row>...</xgql:row>
</xgql:execute>

Exécution d'une requête SQL sur la base, et itération sur les différents résultats de la requête.

<xgql:datasource>$productUrl</xgql:datasource>

Lecture des données sur un disque local, sur un ftp ou par http (Il s'agit d'une extension du langage présent depuis la version 1.5).

<xgql:process>document{$product}/produit/libelle</xgql:process>

Interprétation d'une expression Xpath ou XQuery sur une variable XML.

III - Conclusion

Au travers de cette étude de cas, on voit les avantages XGQL :

1. Unification de moyen d'accès, de modification et de transformation pour des flux XML à partir de base de données relationnelle ou données XML ;

2. Génération de données XML à partir de données relationnelles ;

3. Syntaxe simple ;

4. Maintenance facilitée par un code lisible ;

5. Pas de besoin de recompiler le projet à chaque modification ;

6. Réduction de la complexité des traitements de transformation (pas de code XSLT nécessaire) ;

7. Facilement extensible ;

8. XGQL fonctionne aussi bien sur un Serveur Web qu'en mode API pour des applications ne possédant pas d'interfaces Web.

XGQL dispose de plusieurs extensions et est intégré à plusieurs distributions :

- SWAS XGQL : pack regroupant Jetty, HSQLDBD et XGQL correctement configuré et prêt à l'emploi en mode server ;

- Cocoon XGQLGenerator : Generateur Cocoon pour fichier XGQL ;

- XGQL:DB2XML : extension de langage transformant une base de données relationnelle en base de données XML.

Remerciements

Je tiens à remercier toute l'équipe responsable de la rubrique XML, et tout particulièrement GrandFather, et également Pierre Martins, pour son aide.