Login
Cerca all'interno di JavaPortal
Help
Home Page Documentazione Forum Progetti Partner Pubblica!
Documentazione > Tutorial > Parsing XML: DOM e SAX a confronto
Hide
Best Practices
EJB
Frameworks
Howto
J2EE
J2ME and Wireless
J2SE
JSP e Servlet
Java Application Server
Java IDE/Tools
Java Media
Java Security
Java Sys Admin
Java e XML
Java e SQL
OpenSource Java
Patterns
Repository
Tesi
UML
Web Services
Slide
White Paper di jws.it
project management
Eventi
Groovy

Hai una tesi in Java?
Tesine preparate
per esami?
Pubblica tutto su
JavaPortal!

Scrivi al nostro staff


All4web Day a Milano, 8 maggio


John Fitzgerald Kennedy
L'uomo è il computer più straordinario di tutti


UTILIZZARE LOG4J


Rss Feed
Home Page
Articoli
News
Forum
Classi

  Visualizza Commenti (0) Aggiungi Commento    
Add to Shortcuts
 
Vota l'articolo
Parsing XML: DOM e SAX a confronto
By Simone Panepuccia
10 luglio 2005
Valutazione Acquisita: 20

  Parsing XML: DOM e SAX a confronto
Program Parsing di libro.xml con SAX
Program Parsing di libro.xml con DOM

Il parsing di documenti xml in Java passa principalmente attraverso due famiglie di API: DOM e SAX. In questo articolo ci soffermeremo sulle differenze fra i due approcci e valuteremo pregi e difetti delle due soluzioni proponendo un esempio che, a fronte di un risultato visivamente identico, utilizza le due metodologie per realizzare il parsing di uno stesso documento xml.
Dando per scontata una certa familiarità con la struttura di un documento xml, andiamo a costruire un esempio che utilizzeremo per il test dei due parser.

libro.dtd:

<?xml encoding="UTF-8"?>

<!ELEMENT libro (prefazione?,indice,capitolo+)>
<!ATTLIST libro titolo CDATA #REQUIRED>
<!ATTLIST libro autore CDATA #REQUIRED>
<!ATTLIST libro editore CDATA #REQUIRED>

<!ELEMENT prefazione (#PCDATA)>
<!ATTLIST prefazione autore CDATA #IMPLIED>

<!ELEMENT indice (titolo+)>

<!ELEMENT capitolo (#PCDATA)>

<!ELEMENT titolo (#PCDATA)>

Il dtd (Document Template Descriptor) del nostro documento xml ci indica che dovremo costruire una struttura xml così definita:
1) Un elemento radice chiamato 'libro' con attributi obbligatori 'titolo', 'autore', editore' tutti di tipo CDATA.
2) L'elemento 'libro' potrà avere uno o nessun elemento 'prefazione', un elemento 'indice' (obbligatorio) e uno o più elementi 'capitolo'.
3) L'elemento 'prefazione' è di tipo PCDATA (ossia contiene valori alfanumerici) ed ha un attributo 'autore' non obbligatorio.
4) L'elemento 'indice' non ha attributi ma ha elementi figli 'titolo' (uno o più).
5) Gli elementi 'capitolo' (figlio di 'libro') e titolo (figlio di 'indice') sono semplici elementi contenenti del testo.

Vediamo dunque un esempio di documento xml che rispetta le direttive di libro.dtd:

libro.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE libro SYSTEM "libro.dtd">

<libro titolo="1984" autore="G.Orwell" editore="Mondadori">
      <prefazione autore="Bill Gates">Questo libro non dice il vero. Orwell ha sbagliato...</prefazione>

      <indice>
          <titolo>Parte prima</titolo>
          <titolo>Parte seconda</titolo>
      </indice>
      <capitolo>1. Era una notte buia e tempestosa...</capitolo>
      <capitolo>2. Testo del secondo capitolo...</capitolo>
      <capitolo>3. Testo del terzo capitolo...</capitolo>

</libro>

Le classi del nostro esempio effettueranno il parsing di libro.xml e stamperanno a video tutte le informazioni "utili" che è possibile trarre dagli elementi.



Parsing di libro.xml con SAX top
L'approccio utilizzato da SAX è quello di generare degli eventi nel momento in cui il reader incontra i tag del documento xml. Per intercettare questi eventi la nostra classe parser deve implementare alcune interfacce: ContentHandler, DTDHandler, ErrorHandler.
Per ognuna di esse bisognerà implementare i metodi all'interno dei quali gestire gli eventi scatenati dal parser.
Ai fini del nostro esempio basterà soffermarci su due di questi metodi: startElement() e characters(). Essi sono i due metodi con cui andremo a stampare a video le informazioni che ci interessano.
Per tutti gli altri andremo semplicemente a scrivere la loro chiamata su un log.
Quando il metodo startElement viene chiamato dal parser SAX, ad esso vengono passati dei parametri:

public void startElement(String uri, String localName, String gName, Attributes attributes)

I primi tre sono il namespaceURI, il local name ed il nome completo dell'elemento.
Per il nostro esempio basterà considerare il local name.
L'ultimo parametro che viene passato dal parser è un oggetto Attributes che contiene, ovviamente, gli attributi (se ve ne sono).
Il metodo characters accetta per argomento un array di caratteri (con i relativi start e length) che contiene il testo incluso nell'elemento corrente

function
apri_finestra1(){ msg=window.open('http://www.javaportal.it/docs/saxDom/SaxDocumentParser.htm','
','width=400,height=600'); }
function
apri_finestra2(){ msg=window.open('http://www.javaportal.it/docs/saxDom/DomDocumentParser.java.htm','
','width=400,height=600'); }
function
apri_finestra3(){ msg=window.open('http://www.javaportal.it/docs/saxDom/DomDocumentCleanParser.java.htm','
','width=400,height=600'); }

public void characters(char[] ch, int start, int length)

Link al codice di SaxDocumentParser.java

[Utilizzo: java SaxDocumentParser libro.xml]

 

Fig. 1  Output completo di SaxDocumentParser



Parsing di libro.xml con DOM top

L'approccio di DOM è totalmente diverso da quello di SAX. Abbiamo visto che SAX scorre il documento con un reader e, man mano che intercetta i vari tags, lancia degli eventi chiamando i metodi in cui è contenuta la logica operativa del nostro parser.
Con DOM, invece, tutto l'albero del documento viene caricato in memoria e su di esso possiamo effettuare un'esplorazione seguendo l'algoritmo che più ci aggrada.
In questa struttura ogni elemento del documento xml diventa un nodo dell'albero rappresentato da una classe che implementa l'interfaccia org.w3c.dom.Node. Questa interfaccia fornisce metodi per esplorare o modificare l'albero e per conoscere le proprietà di ogni nodo.

Link al codice di DomDocumentParser.java

[Utilizzo: java DomDocumentParser libro.xml]

La nostra classe di esempio scorre l'albero ricorsivamente e stampa a video tutte le informazioni relative a tutti gli elementi del documento xml.

Fig. 2 Output parziale di DomDocumentParser

Eseguendo il codice dell'esempio possiamo notare che l'output è alquanto diverso da quello del parser SAX. Questo è dovuto al fatto che DOM considera gli elementi del documento in modo più esteso rispetto a SAX. Un'idea di come l'albero degli elementi viene visto da DOM è visibile in figura 3:

Fig. 3 Struttura ad albero degli elementi secondo DOM

Ogni carattere contenuto nel documento è accessibile come se fosse un elemento a sé di tipo Text.
Quindi per ottenere un risultato più leggibile e coerente con l'output ritornato dal parser SAX bisogna necessariamente selezionare gli elementi.
La classe DomDocumentCleanParser realizza il nostro scopo.

Link al codice di DomDocumentCleanParser.java

[Utilizzo: java DomDocumentCleanParser libro.xml]

Considerazioni e confronto fra i due parser

Ambedue le implementazioni presentano, ovviamente, vantaggi e svantaggi che dipendono dalla situazione che il nostro parser deve fronteggiare.
Nel caso di file di dimensioni importanti (per esempio nel caso di export di database) bisogna considerare che DOM carica TUTTO il documento in memoria e lo trasforma in una struttura ad albero quindi, in questo caso, bisogna necessariamente fare i conti con le risorse del nostro sistema: pensare di caricare un intero database in memoria non è una grande idea.
Quindi, in questo caso, forse è meglio rivolgere la nostra attenzione verso SAX.
Di contro, SAX non permette un controllo agevole sulla struttura del documento e, cosa importante, non consente la modifica diretta del nostro file xml. DOM, infatti, oltre a permettere la lettura e la navigazione del documento, ne permette anche la modifica.
Se volessimo modificare un file xml con SAX dovremmo creare un altro file ed effettuare i cambiamenti che ci interessano man mano che il primo documento viene letto (ossia man mano che vengono intercettati gli eventi).

In definitiva possiamo dire che se ci serve una struttura completa del documento in memoria (a patto che il documento non abbia dimensioni mostruose) su cui poter lavorare, DOM può essere la scelta conveniente.
Se dobbiamo lavorare con files di grandi dimensioni e non ci interessa avere un controllo completo sulla struttura del file possiamo tranquillamente optare per SAX.



 Attachments List
Generic DocumentDomDocumentParser.java.txt
Generic DocumentDomDocumentCleanParser.java.txt
Generic DocumentSaxDocumentParser.java.txt
Username:
Password:
To sign up for an account, click register... Register
Hide





Powered By



Campagna Anti-IF


Skin


PARTNER
Zio Budda
HostingJava


LICENZA



Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons

Sitemap  © 2002-2004 Copyright Information. Privacy . Today is domenica 1 agosto 2010