XMLBeans è una libreria scritta dalla Apache che permette di manipolare il contenuto di un file XML fornendo una visione a oggetti dei dati e implementando tutte le funzionalità necessarie allo sviluppatore per gestire in modo automatico le operazioni di lettura, scrittura e validazione di un file XML. La versione che utilizzeremo nel nostro esempio è la 2.3.0.
Mediante XMLBeans è possibile generare delle classi java che permettono di leggere, scrivere o validare un file xml. Per generare le classi occorre preparare un file xsd nel quale sono definite tutte le regole a cui i file XML devono essere conformi.
Per utilizzare XmlBeans bisogna settare le seguenti variabili di ambiente:
- XMLBEANS_HOME contenente il path della root di XMLBeans;
- JAVA_HOME contenente il path della root del JDK;
- Aggiungere al CLASSPATH la libreria %XMLBEANS_HOME%libxbean.jar
è necessario inoltre aggiungere alla variabile di ambiente PATH la cartella bin del JDK e la directory bin di XMLBeans.
Come esempio creeremo le classi java che serviranno per leggere e scrivere file XML del tipo:
Listato 1. Esempio di un XML
<iscritti>
<iscritto matricola="..." nome="..." cognome="...">
<esame voto="..">..</esame>
<esame voto="..">..</esame>
<esame voto="..">..</esame>
</iscritto>
<iscritto matricola="..." nome="..." cognome="...">
<esame voto="..">..</esame>
</iscritto>
<iscritto matricola="..." nome="..." cognome="...">
</iscritto>
...
</iscritti>
Il tag principale è "iscritti
", che può contenere da zero a n tag "iscritto
". Ciascun iscritto ha tre attributi (matricola
, nome
e cognome
) e può contenere zero o n tag esame
. Ciascun esame ha un attributo (voto
) e, il suo valore, rappresenta l'esame sostenuto dallo studente.
Prima di tutto bisogna scrivere il file xsd nel quale viene definita tale struttura. Scrivere a mano un file xsd non è semplicissimo, in aiuto ci viene XMLSpy che ci permette di scriverlo sfruttando le classiche tecniche del drag & drop.
Il file XSD che contiene la struttura del nostro file XML è la seguente:
Listato 2. Esempio di un file XSD
<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSpy v2007 rel. 3 sp1 by Luca -->
<xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns:sf=http://www.sportfantasy.org
targetNamespace="http://www.sportfantasy.org" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="iscritto">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="esame">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="voto">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:maxInclusive value="30"/>
<xs:minInclusive value="18"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="matricola" type="xs:string" use="required"/>
<xs:attribute name="nome" type="xs:string" use="required"/>
<xs:attribute name="cognome" type="xs:string" use="required"/>
</xs:complexType>
<xs:element name="iscritti">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="iscritto" type="sf:iscritto"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Per generare le classi java che permettono di gestire i file XML conformi alla seguente struttura apriamo una shell, portiamoci nella directory nella quale è contenuto il file xsd (iscritti.xsd) appena creato e lanciamo il seguente comando:
scomp iscritti.xsd –out iscritti.jar
Con questo comando viene creata la libreria (iscritti.jar) che contiene le classi java che ci permettono di scrivere e leggere i file XML compatibili con l'xsd. Le classi hanno come package uguale al namespace URI dell'xsd. Nel nostro caso org.sportfantasy
.
La classe principale è IscrittiDocument che incapsula l'intero documento XML. Per ciascun tipo complesso definito nell'xsd è stata generata un'interfaccia e una classe che la implementa. Tutte le classi hanno a disposizione i metodi getter e setter rispettivamente per leggere e scrivere le proprietà dell'oggetto. Ad esempio la classe Iscritto avrà come metodo getNome()
e setNome()
. Naturalmente l'attrbuto nome della classe Iscritto è di tipo stringa così come definito nell'xsd. Poich矩l tag iscritti può contenere n tag iscritto, la classe Iscritti avrà a disposizione un metodo che permette di aggiungere un Iscritto (addNewIscritto()
). Allo stesso modo la classe Iscritto avrà a disposizione un metodo che permette di aggiungere un Esame (addNewEsame()
).
Notiamo che ogni interfaccia che rappresenta un elemento dell'XML schema, contiene un'inner class "Factory", creata secondo il pattern abstract Factory, che permette di creare un oggetto java che incapsula l'elemento. Ad esempio il comando IscrittiDocument.Factory.newInstance()
ci permette di ottenere un'istanza del documento.
Vediamo come utilizzare la libreria per scrivere un file xml conforme alla struttura definita.
Listato 3. Utilizzo della libreria per scrivere un file xml
import java.io.File;
import java.io.IOException;
import org.apache.xmlbeans.XmlOptions;
import org.sportfantasy.IscrittiDocument;
import org.sportfantasy.Iscritto;
import org.sportfantasy.IscrittiDocument.Iscritti;
import org.sportfantasy.Iscritto.Esame;
public class Scrittura
{
public static void main(String[] args) throws IOException
{
//doc è un'istanza del documento xml
IscrittiDocument doc = IscrittiDocument.Factory.newInstance();
//aggiungiamo un tag iscritti al documento
Iscritti studenti = doc.addNewIscritti();
//aggiungiamo uno studente e settiamo i sui attributi
Iscritto studente1 = studenti.addNewIscritto();
studente1.setMatricola("544-843");
studente1.setNome("Pippo");
studente1.setCognome("Baudo");
//aggiungiamo un esame allo studente e settiamo gli attributi
Esame esame1 = studente1.addNewEsame();
esame1.setVoto(18);
esame1.setStringValue("Programmazione");
//aggiungiamo un altro esame allo studente e settiamo gli attributi
Esame esame2 = studente1.addNewEsame();
esame2.setVoto(30);
esame2.setStringValue("Tecnologie WEB");
//aggiungiamo un altro studente e settiamo i sui attributi
Iscritto studente2 = studenti.addNewIscritto();
studente2.setMatricola("503-1092");
studente2.setNome("Mike");
studente2.setCognome("Buongiorno");
//aggiungiamo un esame allo studente e settiamo gli attributi
Esame esame3 = studente2.addNewEsame();
esame3.setVoto(30);
esame3.setStringValue("Analisi 2");
//settiamo le opzioni utilizzate per la stampa o la scrittura
XmlOptions opts = new XmlOptions();
//questa opzione permette di indentare il codice xml
opts.setSavePrettyPrint();
System.out.println(doc.xmlText(opts));
//salviamo il file sul disco
doc.save(new File ("C:/test.xml"), opts);
}
}
Vediamo, infine, come utilizzare la libreria per la lettura di un file xml conforme alla struttura definita.
Listato 4. Utilizzo della libreria per leggere un file xml
import java.io.File;
import org.sportfantasy.IscrittiDocument;
import org.sportfantasy.Iscritto;
import org.sportfantasy.IscrittiDocument.Iscritti;
import org.sportfantasy.Iscritto.Esame;
public class Lettura
{
public static void main(String[] args) throws Exception
{
//caricamento del file xml
IscrittiDocument doc = IscrittiDocument.Factory.parse(new File ("C:/test.xml"));
//root è un'istanza del documento xml
Iscritti root = doc.getIscritti();
//studenti è un array di oggetti Iscritto
Iscritto[] studenti = root.getIscrittoArray();
System.out.println("STUDENTI ISCRITTI: " + studenti.length);
for (int i=0; i<studenti.length; i++)
{
//lettura dell'iesimo iscritto
Iscritto studente = root.getIscrittoArray(i);
System.out.println(studente.getNome() + " " + studente.getCognome() + " " + studente.getMatricola());
for (int j=0; j<studente.getEsameArray().length; j++)
{
//lettura del j'esimo esame
Esame esame = studente.getEsameArray(j);
System.out.println(esame.getStringValue()+ " " + esame.getVoto());
}
System.out.println();
}
}
}