XML ad Eventi
Vediamo uno dei modi possibili per manipolare file XML in Java
Di recente mi sono imbattuto in un messaggio molto originale mentre stavo scrivendo una classe che doveva semplicemente leggere un file di tipo XML con il classico parse DOM. Il messaggio che mi appariva quando con l’IDE di sviluppo andavo a compilare la classe suonavo pressappoco così: “il DOM per fare il parse dei file XML potrebbe non essere supportato in futuro da Java”. Immaginate voi la sorpresa della cosa. Dopo tutto il DOM andava molto bene, era facile da usare anche se caricava molte cose in memoria e i tempi per le varie operazioni di parse non erano sempre favorevoli.
Dopo essermi rilassato ho iniziato a controllare in giro per cercare di capire cosa la Sun(R) aveva utilizzato per ovviare alla perdita futura del DOM. Come al solito si butta un occhio al sito java.sun.com e in particolare all’indirizzo delle pagine che mi interessavano particolarmente java.sun.com/xml. Qui troverete tutto quello che vi serve per scrivere la vostra applicazione per scrivere o leggere file di tipo XML.
Non voglio spiegarvi il tutto per filo e per segno, la documentazione ufficiale è più che esplicativa in quel senso. Vi dico solo che il nuovo modo per operare con xml si basa sulla logica degli eventi. In altre parole il programmatore deve riconoscere l’evento che ha per le mani, tramite una serie di if o più semplicemente con l’uso di switch, e di comportarsi di conseguenza. Devo dire che gli oggetti che lavorano con questa logica sono molto più veloci rispetto al classico DOM, ma non sono molto intuitivi, per lo meno seguono una logica differente rispetto ai precedenti che potrebbero mettere in difficoltà il programmatore. Con me è successo.
Generazione file XML
1 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 |
public class WriteEasyFileXML() { /** Costruttore della classe. */ public WriteEasyFileXML() throws Exception { XMLOutputFactory xof = XMLOutputFactory.newIstance(); /** Definizione di una interfaccia per la gestione dello stream dei dati in scrittura di tipo XML. */ XMLStreamWriter xtw = xof.createXMLStreamWriter(new FileWriter("jugudine.xml")); /** Scrittura del file */ xtw.writeComment("Inserimento di tutti i commenti desiderati"); //inserimento commenti</code></p> xtw.writeStartDocument("UTF-8", "1.0"); /* Apertura del documento. In alternativa si può usare la versione del metodo writeStartDocument("1.0") dove il valore dell'encoding è "UTF-8" oppure semplicemente writeStartDocument(), dove il valore dell'encoding è "UTF-8" e la versione la "1.0". */ xtw.writeStartElement("jugUdine"); /* Apertura del tag iniziale */ xtw.writeStartElement("membri"); /* Apertura del tag "membri" */ xtw.writeStartElement("membro"); /* Apertura del tag "membro" */ xtw.writeAttribute("nome", "Mattia Zuliani"); /*Inserimento Attributo nome=valore */ xtw.writeCharacters("Non capisco nulla di quello che faccio!!! :->"); /*Inserimento stringa tra i tag */ xtw.writeEndElement(); /* Chiusura del tag membro */ xtw.writeStartElement("membro"); xtw.writeAttribute("nome","Ivan Codarin"); xtw.writeCharacters("Ciao giovane, come Va?"); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeEndDocument(); /* Chiusura del documento */ xtw.flush(); /* Scrittura del file */ xtw.close(); /* Chiusura del file */ } public static void main(String[] args) { try { WriteEasyFileXML(); } catch (Exception e) {} } } |
Il risultato finale di tutto questo codice è:
1 2 3 4 5 6 7 8 9 |
<jugUdine> <membri> <membro nome="Mattia Zuliani">Non capisco nulla di quello che faccio!!! :-></membro> <membro nome="Ivan Codarin">Ciao giovane, come Va?</membro> </membri> </jugUdine> |
L’intero contenuto del file si trova in jugUdine.xml. Se il file esiste allora verrà sovrascritto, se non esiste verrà automaticamente creato sul momento al percorso specificato.
Lettura di un File XML
Per la lettura del file xml si possono usare due soluzioni, quella basata sullo stream di lettura e quello meno efficiente degli eventi. Per questo esempio ho preferito usare il secondo metodo, quello degli eventi. Con questo metodo si ottengono degli oggetti ad ogni passo di analisi da parte della classe che lo implementa. Tale oggetto deve essere riconosciuto e poi da noi analizzato.
Un esempio di codice è il seguente:
1 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 |
public WriteXML { public static void main(String[] args) { XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader xmlr = factory.createXMLStreamReader( filename, new FileInputStream(filename)); int eventType = xmlr.getEventType(); printStartDocument(xmlr); while ( xmlr.hasNext() ) { eventType = xmlr.getEventType(); printStartDocument(eventType); QName qName = xmlr.getQName(); System.out.println(qName.toString()); } } private void printDocument(int event) { String text = ""; switch ( event ) { case XMLEvent.START_ELEMENT: text = "START_ELEMENT"; break; case XMLEvent.END_ELEMENT: text = "END_ELEMENT"; break; case XMLEvent.PROCESSING_ISTRUCTION: text = "PROCESSING_ISTRUCTION"; break; case XMLEvent.CHARACTERS: text = "CHARACTERS"; break; case XMLEvent.COMMENT: text = "COMMENT"; break; case XMLEvent.START_DOCUMENT: text = "START_DOCUMENT"; break; case XMLEvent.END_DOCUMENT: text = "END_DOCUMENT"; break; case XMLEvent.ATTRIBUTE: text = "ATTRIBUTE"; break; case XMLEvent.DTD: text = "DTD"; break; case XMLEvent.CDATA: text = "CDATA"; break; case XMLEvent.SPACE: text = "SPACE"; break; } System.out.println(text); } } |
La cosa più interessante di questo pacchetto messo a disposizione da Java è il fatto che ci permette di avere un canale di stream aperto sia in lettura che in scrittura sullo stesso file. Questo ci permette di operare in modo più comodo sui tag XML.