Je me suis retrouvé, il y a quelques mois de cela, avec un fichier “xml” contenant toutes les informations dont j’avais besoin, ou presque, pour pouvoir initialiser ma base de données.
Il ne me restait plus qu’à programmer un petit “wrapper” de
XML vers
SQL. Et avant de me lancer dans des développements avec mon language préféré
C#, je me suis souvenu qu’il existait un language de transformation de
XML, appelé
XSLT, qui permettait de transformer un fichier “
xml” en de nombreuses autres choses dont
html,
doc,
pdf,
wml et bien d’autres choses encore.
Alors pourquoi ne pas utiliser
XSLT pour transformer mon fichier
XML en fichier
SQL que je n’aurais alors plus qu’ à importer dans ma base de données préférée.
Pour information, il existe plusieurs languages de requêtage
XML dont
XQUERY et
XPATH.
Pour faciliter nos manipulations de
XML nous allons utiliser une version d’évaluation d’un excellent outil appelé
Altova XMLSpy qui nous permet de créer et tester nos requêtes avant de les appliquer à notre fichier “
xml” source et produire notre fichier “
sql” destination.

Description du contexteEn observant le fichier “
xml” source on note qu’il contient 2 catégories d’objets qui nous intéressent plus particulièrement: l’objet “
Computer” et l’objet “
User”. On constate que le champ “
computerid” nous manque dans le fichier “
xml” source pour permettre la création de l’objet “
Computer” dans la table '”
Computer” de la base de données. De même un champ “
guid” nous manque pour permettre de créer un objet “
User” dans la table “
User” de la base de données.
Dans le fichier “
xml” source, le paramètre “
UserID” de l’objet “
Computer” correspond au paramètre “
UserID” de l’objet “
User” auquel il appartient.
Dans la base de données, la valeur du “
guid” de l’objet “
Computer” doit avoir la valeur du “
guid” de l’objet “
User” auquel l’objet “
Computer” appartient.
Le paramètre “
computerid” de la la table “
Computer” est initialisé à une valeur unique incrémentée à partir de 200.
Le paramètre “
guid” de la la table “
User” est initialisé à une valeur unique incrémentée à partir de 100.
Création des fichiers "xsl"La première étape consiste à créer le(les) fichiers “
xsl” décrivant la(les) transformation(s) à effectuer.
Commençons par écrire le fichier “
guid_generator.xsl” ci-dessous permettant de créer le champ “
guid” pour l’objet “
User”:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="guid" select="100"/>
<xsl:template match="@*node()">
<xsl:copy>
<xsl:apply-templates select="@*node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="User">
<User>
<xsl:apply-templates select="@* *"/>
<guid>
<xsl:choose>
<xsl:when test="not(preceding-sibling::*)">
<xsl:value-of select="$guid"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$guid + count(preceding-sibling::*)"/>
</xsl:otherwise>
</xsl:choose>
</guid>
</User>
</xsl:template>
Le champ “
guid” est initialisé à 100. Puis on copie simplement le contenu du fichier source; et si l’objet
XML est “
User” alors on ajoute aux champs existants, un champ “
guid” auquel on donne une valeur initiale (i.e. 100) à laquelle on ajoute le nombre d’objets “
User” que l’on vient de parcourir. Simple et efficace!
Il ne nous reste plus qu’à transformer le fichier généré précédemment en fichier “
sql” en créant le fichier “
insert_generator.xsl” ci-dessous. On profite cependant de cette transformation pour donner une valeur au champ “
computerid” nécessaire à la création de la table “
Computer” (cette valeur est initialisée à 200):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:variable name="computerid" select="200"/>
<xsl:template match="/">
<xsl:apply-templates select="//ComputerList"/>
<xsl:apply-templates select="//UserList"/>
</xsl:template>
<xsl:template match="User">
<xsl:text>INSERT INTO USER"("GUID", …, "MODIFDATE")
VALUES(</xsl:text>
<xsl:value-of select="./guid"/>
<xsl:text>,'</xsl:text>
<!—…-->
<xsl:text>SYSDATE);
</xsl:text>
</xsl:template>
<xsl:template match="Computer">
<xsl:param name="temp"><xsl:value-of select="./UserID"/></xsl:param>
<xsl:text>INSERT INTO COMPUTER"("COMPUTERID","GUID",…, "MODIFDATE")
VALUES(</xsl:text>
<xsl:choose>
<xsl:when test="not(preceding-sibling::*)">
<xsl:value-of select="$computerid"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$computerid + count(preceding-sibling::*)"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text>,</xsl:text>
<xsl:value-of select="//UserList/User[UserID=$temp]/guid"/>
<xsl:text>,'</xsl:text>
<!—…-->
<xsl:value-of select="./ExpirationDate"/>
<xsl:text>');
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Comme dit précédemment, notons qu’un objet “
Computer” est associé à un objet “
User” dans le fichier source “
xml” au travers du paramètre “UserID”. La valeur du paramètre “
UserID” de l’objet “Computer” courant est sauvegardée dans un paramètre appelé “
temp” afin de permettre la récupération du “
guid” correspondant à l’objet “
User” ayant un “
UserID” correspondant à “temp”, car c’est ce “guid” là qui doit être associé à l’objet “
Computer” courant. Est-ce clair! Oui, bon on continue…
Les fichiers “
xsl” nécessaires à nos transformations sont enfin écrits. Il ne nous reste plus qu’à installer notre parseur
XML préféré, j’ai nommé
Xalan installé sous C:\.
La génération du fichier “
sql” se passe en 2 étapes:
cd C:\xalan-j_2_7_1
java -classpath "C:\xalan-j_2_7_1\xalan.jar";"C:\xalan-j_2_7_1\xercesImpl.jar";"C:\xalan-j_2_7_1\serializer.jar";"D:\xalan-j_2_7_1\xml-apis.jar" org.apache.xalan.xslt.Process -IN input.xml -XSL guid_generator.xsl -OUT output.xml
pause
java -classpath "C:\xalan-j_2_7_1\xalan.jar";"C:\xalan-j_2_7_1\xercesImpl.jar";"C:\xalan-j_2_7_1\serializer.jar";"D:\xalan-j_2_7_1\xml-apis.jar" org.apache.xalan.xslt.Process -IN output.xml -XSL sql_insert_generator.xsl -OUT output.sql
pause
La première étape permet de prendre le fichier “
xml” source appelé “
input.xml” et le transformer en un autre fichier “
xml” appelé “
output.xml” contenant également un champ “
guid” incrémenté. Ce champ est nécessaire pour insérer l’objet “
User” dans la table “
User”. C’est le fichier “
guid_generator.xsl” qui permet cette transformation.
La deuxième étape prend en entrée le fichier “
output.xml” et le transforme en “
output.sql”. C’est le fichier “
insert_generator.xsl” qui permet cette transformation. Il permet également de créer un champ “
computerid” et de lui donner une valeur unique pour permettre la création de l’objet “
Computer”' dans la table “
Computer” de la base de données.
Le tour est joué!
Note: pour des raisons de confidentialité vous ne trouverez pas les fichiers “
input.xml”, “
output.xml” et “
output.sql”. Mais je suis à votre entière disposition pour répondre à toutes questions!