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. Etude 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 regroupants 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
Sélectionnez
<produit>
	<libelle>Marteau</libelle>
	<description_courte>Marteau à enfoncer les clous de girofle</description_courte>
	<description_longue>Un magnifique marteau à enfonce 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.

Image non disponible
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).

Image non disponible
Figure 2 - Traitement des flux avec SQL/Java/XSLT

Le traitement se fait en 4 étapes :

Etape 1 - connexion à la base

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

 
Sélectionnez
//Initialisation
ResultSet result = null;
Statement statement = null;
Connection connect = null;
// Connection à la base
 
try {
    Class.forName(className);
    connect = java.sql.DriverManager.getConnection(url, name, password);
    connect.setAutoCommit(false);
 
} catch (Exception e) {
// gestion de l'exception
}
 
// execution 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 connection à la base de donnée
try {
    connect.close();
} catch (Exception e) {
// gestion de l'exception
}

Etape 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

 
Sélectionnez
          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();

Etape 3 - Génération du XML

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

 
Sélectionnez
myXMLResult.append(xmlResult);

Etape 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 'libéllé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é.

Image non disponible
Figure 3 - Traitement des flux avec XGQL

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

 
Sélectionnez
<?xml version="1.0" encoding="UTF-8"?>
 
<xgql:root xmlns:xgql="http://www.symeria.com/xgql/">
	<products>
 
		<!-- definition de la requete -->                            
		<xgql:var name="select"> SELECT URL FROM ANNU_PRODUCT WHERE IDTHEME=1</xgql:var>
 
		<!-- execution de la requete -->
		<xgql:execute name="select">
 
			<!-- iteration sur les differents résultats -->
			<xgql:row>
				<xgql:var name="productUrl">
					<xgql:column name="url" wrap="false"/>
				</xgql:var>
 
				<!-- récuperation des differents 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 :

 
Sélectionnez
<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 !) :

 
Sélectionnez
<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érentes résultats de la requête.

 
Sélectionnez
<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ésente depuis la version 1.5).

 
Sélectionnez
<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 relationnelles 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 relationnelles 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.