CREARE UN FILE XML IN JAVA UTILIZZANDO LE LIBRERIE STANDARD DOM.
In questo articolo verrà presentato come creare, scrivere, un file xml con le librerie standard DOM che troviamo in ogni distribuizone di JSE.
Non parliamo dell'architettura del file xml, come è strutturato, dato che in rete sono disponibili numerose informazioni, ma illustro come ho risolto l'esigenza di scrivere un file xml. Per chi interessato alla struttura dell'xml una particolare sorgente di informazioni, molto utile, anche se un pò datata, ma i concetti sono gli stessi, la potete reperire all'indirizzo: http://www.cafeconleche.org/books/xmljava/chapters/index.html.
Di seguito la struttura base del file xml che deve essere scritto, che è utilizzato come data base dell'applicazione:
<?xml version="1.0" encoding="UTF-8"?>
<!-- xml MEP DATA BASE --> //questo è un commento
<xDB_MEP> //questo è l'elemento root
<RIFERIMENTI>
<DataGenerazione>4/1/2019 12:31:57</DataGenerazione>
<DataModifica>4/1/2019 12:31:57</DataModifica>
<Versione>0.0.0.0</Versione>
</RIFERIMENTI>
<PROGRAMMA Id="1" cancellato="0"> //questo è un nodo con attributi
<Codice>qwertyuniop</Codice>
<Misura>45.0</Misura>
<Tagli>5</Tagli>
<Beta1>0</Beta1>
<Beta2>0</Beta2>
<GruppoMateriale>2</GruppoMateriale>
<Geometria>2</Geometria>
<L>0.0</L>
<H>0.0</H>
<D>78.0</D>
<T>0.0</T>
<F>78.0</F>
<S>56</S>
<OverrideFInizio>0</OverrideFInizio>
<SpazioOverrideFInizio>0.0</SpazioOverrideFInizio>
<OverrideFFine>0</OverrideFFine>
<SpazioOverrideFFine>0.0</SpazioOverrideFFine>
<OverrideSInizio>0</OverrideSInizio>
<SpazioOverrideSInizio>0.0</SpazioOverrideSInizio>
<OverrideSFine>0</OverrideSFine>
<SpazioOverrideSFine>0.0</SpazioOverrideSFine>
<IndiceLibreriePLC>0</IndiceLibreriePLC>
<Fcta>6.0</Fcta>
<Riserva_0>riserva_0</Riserva_0>
<Riserva_1>riserva_1</Riserva_1>
<Riserva_2>riserva_2</Riserva_2>
<Riserva_3>riserva_3</Riserva_3>
<Riserva_4>riserva_4</Riserva_4>
<Riserva_5>riserva_5</Riserva_5>
<Riserva_6>riserva_6</Riserva_6>
<Riserva_7>riserva_7</Riserva_7>
<Riserva_8>riserva_8</Riserva_8>
<Riserva_9>riserva_9</Riserva_9>
<Riserva_10>riserva_10</Riserva_10>
<Data_Gen>4/1/2019 12:31:57</Data_Gen>
<Data_Canc>4/1/2019 12:31:57</Data_Canc>
<Data_Mod>4/1/2019 12:31:57</Data_Mod>
<crc_32>nu</crc_32>
</PROGRAMMA>
</xDB_MEP>
Distinguiamo: una sezione RIFERIMENTI che contiene dati generali, una sezione PROGRAMMA che contiene i dati del relativo programma. La sezione RIFERIMENTI è unica per il file, la sezione PROGRAMMA rappresenta il record e può essere ripetuta n volte.
Il codice: fatto per provare la funzionalità, poi potete tranquillamente renderlo più compatto con variabili di appoggio degli elementi da creare.
/**
* metodo per creare un nuovo file xml, secondo la struttura di xMep
*/
public int creaFile(JTable tab, File f) {
int ris = -1;
int passo = 0;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
try {
Document doc = dbf.newDocumentBuilder().newDocument();
doc.setXmlStandalone(true);
//Element root = doc.getDocumentElement();
doc.appendChild(doc.createComment(COMMENTO));
try {
Element radice = doc.createElement(RADICE);
passo = ++passo; //1
doc.appendChild(radice);
passo = ++passo; //2
Element rif = doc.createElement("RIFERIMENTI");
passo = ++passo; //3
radice.appendChild(rif);
passo = ++passo; //4
DataManager data = new DataManager();
String dt = data.dataGenerazione((byte)0);
int i;
//aggiunge la sezione RIFERIMENTI
for (i=0; i < 3; i++) {
String nc = "RIF_" + i;
Element campo;
if (i < 2) {
if (i==0) {
campo = doc.createElement(RIF_0);
}
else {
campo = doc.createElement(RIF_1);
}
passo = ++passo;
campo.setTextContent(dt);
}
else {
passo = ++passo;
campo = doc.createElement(RIF_2);
passo = ++passo;
campo.setTextContent(VERS);
}
passo = ++passo;
rif.appendChild(campo);
passo = ++passo;
}
//aggiungi i programmi
for (i=0; i<tab.getRowCount(); i++) {
int numprg = i+1;
String aux = "";
aux = aux + numprg; //contiene il numero di programma
Element prg = doc.createElement("PROGRAMMA");
passo = ++passo;
prg.setAttribute("Id", aux);
passo = ++passo;
prg.setAttribute("cancellato", "0");
passo = ++passo;
radice.appendChild(prg);
//recupera gli elementi della riga da salvare
RowManager riga = new RowManager();
passo = ++passo;
riga.RowManagerDammiDatiRiga(tab, i);
passo = ++passo;
Element cod = doc.createElement("Codice");
passo = ++passo;
aux = riga.getCodice();
if (aux.equals("") || aux.equals(null)) {
aux = " ";
}
cod.setTextContent(aux);
passo = ++passo;
prg.appendChild(cod);
Element mis = doc.createElement("Misura");
mis.setTextContent(riga.getMisura());
prg.appendChild(mis);
passo = ++passo;
Element el = doc.createElement("Tagli");
el.setTextContent(riga.getTagli());
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("Beta1");
el.setTextContent("0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("Beta2");
el.setTextContent("0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("GruppoMateriale");
aux = "";
aux = aux + riga.getGruppo();
el.setTextContent(aux);
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("Geometria");
aux = "";
aux = aux + riga.getTipo();
el.setTextContent(aux);
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("L");
el.setTextContent(riga.getLarghezza());
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("H");
el.setTextContent(riga.getAltezza());
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("D");
el.setTextContent(riga.getDiametro());
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("T");
el.setTextContent(riga.getSpessore());
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("F");
el.setTextContent(riga.getF());
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("S");
el.setTextContent(riga.getS());
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("OverrideFInizio");
el.setTextContent("0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("SpazioOverrideFInizio");
el.setTextContent("0.0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("OverrideFFine");
el.setTextContent("0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("SpazioOverrideFFine");
el.setTextContent("0.0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("OverrideSInizio");
el.setTextContent("0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("SpazioOverrideSInizio");
el.setTextContent("0.0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("OverrideSFine");
el.setTextContent("0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("SpazioOverrideSFine");
el.setTextContent("0.0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("IndiceLibreriePLC");
el.setTextContent("0");
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("Fcta");
el.setTextContent(riga.getFcta());
prg.appendChild(el);
passo = ++passo;
for (int j=0; j< 11;j++) {
aux = "Riserva_" + j;
el = doc.createElement(aux);
aux = "riserva_" + j;
el.setTextContent(aux);
prg.appendChild(el);
passo = ++passo;
}
el = doc.createElement("Data_Gen");
el.setTextContent(dt);
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("Data_Canc");
el.setTextContent(dt);
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("Data_Mod");
el.setTextContent(dt);
prg.appendChild(el);
passo = ++passo;
el = doc.createElement("crc_32");
el.setTextContent("nu");
prg.appendChild(el);
passo = ++passo;
}
}
catch (DOMException dex) {
dex.printStackTrace();
ris = 10 + passo;
switch (passo) {
case 0: ris = 10; break; //errore nella creazione dell'elemento radice
case 1: ris = 11; break; //errore nell'aggiunta del nodo radice
case 2: ris = 12; break; //errore nella creazione dell'elemento RIFERIMENTI
case 3: ris = 13; break; //errore nell'aggiunta del nodo RIFERIMENTI
case 4: ris = 14; break; //errore nella creazione dell'elemento RIF_0
case 5: ris = 15; break; //errore nell'aggiunta del testo del nodo RIF_0
case 6: ris = 16; break; //errore nell'aggiunta dell'elemento RIF_0
case 7: ris = 17; break; //errore nella creazione dell'elemento RIF_1
case 8: ris = 18; break; //errore nell'aggiunta del testo del nodo RIF_1
case 9: ris = 19; break; //errore nell'aggiunta dell'elemento RIF_1
case 10: ris = 20; break; //errore nella creazione dell'elemento RIF_2
case 11: ris = 21; break; //errore nell'aggiunta del testo del nodo RIF_2
case 12: ris = 22; break; //errore nell'aggiunta dell'elemento RIF_2
}
}
try {
salvaFileXml(doc, f);
ris = 0;
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ris = 1;
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//errore durante la generazione del documentbuilder
ris = 99;
}
return ris;
}
La routine SalvaFileXml:
/*
* metoso per salvare il file xml nuovo
*/
public byte salvaFileXml(Document doc, File f) throws TransformerConfigurationException {
byte ris = 0;
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t= tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "Yes");
DOMSource src = new DOMSource(doc);
StreamResult result = new StreamResult(f);
try {
t.transform(src, result);
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ris = 1;
}
return ris;
}
RowManager è una classe per recuperare gli elementi di una riga di una tabella. Dato che il tutto ècontenuto in un blocco Try Catch, la variabile passo è utilizzata per capire in quale punto di generazione del'Xml è accaduto l'errore.