I. Présentation▲
XMLBeans est un outil qui permet de faire du databinding Java/XML.
Il a été initié en 2003 par David Bau, de BEA, puis est devenu open source puisque cédé à la fondation Apache.
On peut télécharger la librairie sur http://xmlbeans.apache.org/
La version actuelle est 2.3.0.
Elle offre la possibilité de mapper un document XML en objets Javabeans.
Au lieu de parcourir un arbre DOM ou de faire de l'évènementiel avec SAX par exemple, on passe par des getters et setters.
On peut générer des fichiers XML à partir de classes Java, ou inversement, générer des objets Java (POJOs) à partir de fichiers XML.
Les outils utilisés dans cet article sont :
- Eclipse 3.4 Ganymede
- Java 1.5
- Altova XMLSpy version 2008
- XMLBeans 2.3.0
- Saxon 8.8 (fichier saxonb8-8j.zip), une implémentation open-source de XSLT 2.0 et XPath 2.0, et XQuery 1.0
II. Schéma XML et DTD▲
Il est nécessaire de faire quelques rappels rapides.
- Une DTD (Document Type Definition) : une DTD permet de vérifier qu'un document XML est valide. Il est valide s'il est conforme aux règles sémantiques définies dans la DTD.
- Un schéma XML : aussi appelé XSD (XML Schema Definition), il est une alternative aux DTDs.
II-A. Validation via un Schéma XML▲
A l'aide de XMLSpy (ou tout simplement d'un browser), on peut valider le fichier XML, par rapport au schéma XML suivant.
II-B. Validation via une DTD▲
Les schémas XML présentent plusieurs avantages par rapport aux DTDs :
- une syntaxe XML
- possibilité de spécifier les types des données
- espace de nommage (namespace), ce qui implique que les règles pour définir certains éléments seront à un certain endroit tandis que les règles pour valider les règles pour définir d'autres éléments seront à un autre endroit.
III. Exemple▲
Pour ce tutoriel, je vais prendre comme exemple de base le cas d'un parc automobile qu'on peut découper de la façon suivante :
On peut automatiquement créer le Schéma XML grâce à XMLSpy :
IV. Génération des classes▲
Pour utiliser XMLBeans, il faut définir la variable d'environnement XMLBEANS_HOME, elle pointe vers le répertoire d'installation de XMLBeans.
On va créer les classes Java à partir du Schéma XML.
Pour cela, il y a 2 façons de faire. Soit on passe par l'utilitaire SCOMP, soit on utilise une tâche Ant xmlbean.
IV-A. L'utilitaire SCOMP (Schema Compiler)▲
Dans une fenêtre DOS, on tape la commande scomp :
Après avoir ajouter XMLBEANS_HOME/bin dans le PATH (set PATH=%PATH%;%XMLBEANS_HOME%\bin\), on peut taper la commande suivante :
>scomp -src src -javasource 1.5 -out parcAuto.xsd
Note: pour éviter d'avoir un java.io.IOException, il faut modifier le script scomp.cmd en changeant la ligne suivante :
java -classpath "%cp%" org.apache.xmlbeans.impl.tool.SchemaCompiler %*
par
%JAVA_HOME%/bin/java -classpath "%cp%" org.apache.xmlbeans.impl.tool.SchemaCompiler %*
On obtient la hiérachie suivante :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
D:\tutorielXMLBeans\
D:\tutorielXMLBeans\parcAuto.xsd
D:\tutorielXMLBeans\xmltypes.jar (contient les classes compilées et des fichiers XSB nécessaires à XMLBeans)
D:\tutorielXMLBeans\src (contient les interfaces et classes générées)
D:\tutorielXMLBeans\src\noNamespace (pas de namespace dans le Schema)
D:\tutorielXMLBeans\src\noNamespace\CouleurDocument.java
D:\tutorielXMLBeans\src\noNamespace\MarqueDocument.java (type complexe Marque)
D:\tutorielXMLBeans\src\noNamespace\NombreDocument.java
D:\tutorielXMLBeans\src\noNamespace\NomDocument.java
D:\tutorielXMLBeans\src\noNamespace\ParcautomobileDocument.java (element racine Parcautomobile)
D:\tutorielXMLBeans\src\noNamespace\PuissanceDocument.java
D:\tutorielXMLBeans\src\noNamespace\VehiculeDocument.java (type complexe Vehicule)
D:\tutorielXMLBeans\src\noNamespace\impl
D:\tutorielXMLBeans\src\noNamespace\impl\CouleurDocumentImpl.java
D:\tutorielXMLBeans\src\noNamespace\impl\MarqueDocumentImpl.java
D:\tutorielXMLBeans\src\noNamespace\impl\NombreDocumentImpl.java
D:\tutorielXMLBeans\src\noNamespace\impl\NomDocumentImpl.java
D:\tutorielXMLBeans\src\noNamespace\impl\ParcautomobileDocumentImpl.java
D:\tutorielXMLBeans\src\noNamespace\impl\PuissanceDocumentImpl.java
D:\tutorielXMLBeans\src\noNamespace\impl\VehiculeDocumentImpl.java
Il faut inclure le jar xmltypes.jar dans le CLASSPATH.
IV-B. Tâche Ant xmlbean▲
Une tâche ANT existe pour compiler un fichier XSD en classe XMLBeans. Elle permet d'obtenir un fichier JAR mais aussi le code source.
Après lancement de la tâche, on obtient la hiérarchie suivante dans Eclipse :
L'archive tuto.jar contient les fichiers XSB et est à mettre dans le build path du projet :
V. Génération d'un fichier XML▲
Grâce aux classes engendrées par XMLBeans, on peut manipuler les différents éléments XML comme des objets java Beans.
Chaque interface possède une classe factory avec une méthode statique newInstance() pour créer une instance du type de la classe.
Les valeurs fixes sont représentées avec des énumérations.
On valide par rapport au schéma XML l'instance nouvellement créée avec la méthode validate() de l'interface XmlObject.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
package com.developpez.tutoriel;
import java.io.File;
import java.io.IOException;
import noNamespace.ParcautomobileDocument;
import noNamespace.CouleurDocument.Couleur;
import noNamespace.MarqueDocument.Marque;
import noNamespace.NomDocument.Nom;
import noNamespace.ParcautomobileDocument.Parcautomobile;
import noNamespace.PuissanceDocument.Puissance;
import noNamespace.VehiculeDocument.Vehicule;
import noNamespace.VehiculeDocument.Vehicule.Modele;
import org.apache.xmlbeans.XmlOptions;
public class GenerationXML {
public static void main(String[] args) throws IOException
{
//parc est une instance du document XML
ParcautomobileDocument parc = ParcautomobileDocument.Factory.newInstance();
//ajout d'un tag Parcautomobile au document XML
Parcautomobile parcautomobile = parc.addNewParcautomobile();
// ajout d'un Vehicule au parc automobile
Vehicule vehicule1 = parcautomobile.addNewVehicule();
vehicule1.setModele(Modele.COUPE);
//Vehicule de modèle COUPE, 1ère marque
Marque marque1 = vehicule1.addNewMarque();
marque1.setNom(Nom.RENAULT);
Puissance puissance1 = Puissance.Factory.newInstance();
puissance1.setChevaux((byte)8);
puissance1.setVitessemax((short)280);
marque1.setPuissance(puissance1);
marque1.setNombre((byte)18);
marque1.setCouleur(Couleur.NOIR);
//Vehicule de modèle COUPE, 2ème marque
Marque marque2 = vehicule1.addNewMarque();
marque2.setNom(Nom.PEUGEOT);
Puissance puissance2 = Puissance.Factory.newInstance();
puissance2.setChevaux((byte)11);
puissance2.setVitessemax((short)320);
marque2.setPuissance(puissance2);
marque2.setNombre((byte)10);
marque2.setCouleur(Couleur.ROUGE);
// ajout d'un Vehicule au parc automobile
Vehicule vehicule2 = parcautomobile.addNewVehicule();
vehicule2.setModele(Modele.BERLINE);
//Vehicule de modèle COUPE, 1ère marque
Marque marque3 = vehicule2.addNewMarque();
marque3.setNom(Nom.MERCEDES);
Puissance puissance3 = Puissance.Factory.newInstance();
puissance3.setChevaux((byte)10);
puissance3.setVitessemax((short)330);
marque3.setPuissance(puissance3);
marque3.setNombre((byte)9);
marque3.setCouleur(Couleur.GRIS);
//Vehicule de modèle COUPE, 2ème marque
Marque marque4 = vehicule2.addNewMarque();
marque4.setNom(Nom.BMW);
Puissance puissance4 = Puissance.Factory.newInstance();
puissance4.setChevaux((byte)12);
puissance4.setVitessemax((short)300);
marque4.setPuissance(puissance4);
marque4.setNombre((byte)7);
marque4.setCouleur(Couleur.BLEU);
// Validation de l'instance du schema XML
boolean estValide = parc.validate();
if (! estValide){
System.err.println("Attention, cette instance du schema n'est pas valide ! ");
return;
}
XmlOptions opts = new XmlOptions();
//cette option permet d'indenter le code
opts.setSavePrettyPrint();
System.out.println(parc.xmlText(opts));
parc.save(new File ("d:/parcAuto.xml"), opts);
}
}
On obtient en sortie un fichier XML parcAuto.xml identique au précédent.
VI. Parsing d'un fichier XML▲
Et inversement, il est possible de parcourir un fichier XML de façon totalement objet.
On utilise la méthode parse() de l'interface ParcautomobileDocument pour charger le fichier et ensuite le parcourir.
Sortie de la console :
VII. L'interface XMLCursor▲
L'interface XmlCursor fournit une navigation efficace dans un arbre XML, à la manière d'un curseur en PL/SQL.
Le curseur représente un endroit spécifique (noeud) dans le document XML.
Dans l'API XMLCursor, un document XML est constitué par des tokens.
Concrètement, un token est soit un type d'attribut, soit un début d'élément, soit une fin d'élément etc.
Exemple: on peut insérer un nouveau modèle de véhicule au niveau de l'élément racine <parcautomobile> , au tout début.
Résultat de l'insertion :
VIII. XQuery▲
Pour une recherche avancée dans le document XML, on doit passer par Xquery.
XQuery est à XML ce que SQL est aux bases de données.
Si on veut récupérer dans le document XML le nombre de Peugeot dans le parc automobile, on peut naviguer dans l'arbre pour aller se positionner directement sur le sous-élément <nombre> de l'élément <marque> , lui-même sous-élément de l'élément <vehicule modele="coupe">.
La méthode execQuery(queryExpression) de l'interface XmlCursor prend en paramètre une expression Xquery.
Note: il est nécessaire d'installer la librairie Saxon (processor XSLT et XQuery).
En effet, pour des raisons d'incompatibilités de licences, cette librairie n'est malheureusement pas incluse dans XMLBeans.
Résultat :
Note: il existe une autre interface graphique, beaucoup plus simple que XMLSpy, pour rapidement tester les requêtes XQuery, à savoir XQuisitor.
IX. XPath▲
On peut passer par des expressions XPath, que l'on donne en paramètre de la méthode selectPath(String).
Elle retourne des sélections.
Et on navigue ensuite à l'aide de la méthode toNextSelection(), pour itérer à travers les sélections.
Exemple : afficher tous les noms de marque de vehicules dans le fichier XML.
Résultat de la recherche :