JAVA SAX PARSER

Il parsing di documenti XML è un’operazione molto diffusa e utile. In Java esistono sostanzialmente due approcci: DOM e SAX. Mentre SAX si basa sulla generazione di eventi quando si verificano determinate situazioni (es. inizio del documento, inizio di un elemento, fine di un elemento...) e non mantiene in memoria il documento, con DOM (leggi qui) tutto l'albero del documento viene caricato in memoria e possiamo lavorare su di esso come meglio preferiamo. Appare subito evidente che SAX utilizza al meglio le risorse (DOM soffre con documenti XML molto grandi), ma non consente di navigare il documento al contrario, né di modificare o creare documenti XML.

Un parser SAX ("Simple API for XML") è orientato al flusso di dati, cioè legge il documento XML generando degli eventi quando incontra alcuni elementi strutturati. Non mantiene quindi tutto l'albero del documento XML in memoria (con grande risparmio di memoria) e gli eventi possono essere catturati e gestiti da rispettivi metodi Java. Possono essere generati i seguenti eventi (la lista non è completa):

L'oggetto Java responsabile di catturare gli eventi deve implementare la classe org.xml.sax.helpers.DefaultHandler e i metodi di gestione degli eventi:


public class MySaxParser extends DefaultHandler {

	public void startDocument() throws SAXException {}

	public void endDocument() throws SAXException {}
	
	/**
	 * Recognizes an XML element to index
	 * @param namespaceURI String namespace URI or an empty String
	 * @param localName String name of element (with no namespace prefix)
	 * @param rawName String XML 1.0 of element name: [namespace prefix]:[localName]
	 * @param atts Attributes list for this element
	 * @throws SAXException when things go wrong
	 */
	public void startElement (String namespaceURI, String localName, 
		String rawName, Attributes atts) throws SAXException {

	}
	
	/**
	 * Buffers management and end of record
	 * @param namespaceURI String URI of namespace this element is associated with
	 * @param localName String name of element without prefix
	 * @param rawName String name of element in XML 1.0 form
	 * @throws SAXException when things go wrong
	 */
	public void endElement (String namespaceURI, String localName, 
		String rawName) throws SAXException {
	}
	
	/**
	 * @param ch char[] character array with character data
	 * @param start int index in array where data starts.
	 * @param length int length of data in array.
	 * @throws SAXException when things go wrong
	 */
	public void characters(char ch[], int start, int length)
		throws SAXException {
	}

	public void ignorableWhitespace(char ch[], int start, int length)
		throws SAXException {
	}

}    				

Per usare l'oggetto DefaultHandler occorre creare un SAXParser ed eseguire esplicitamente uno dei suoi metodi parse():


File f = new File("filename.xml"); //an XML file
SAXParserFactory  spf = SAXParserFactory.newInstance();
spf.setValidating(false);
spf.setNamespaceAware(false);
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(f ,new MySaxParser());

Si tenga presente che l'oggetto da noi definito MySaxParser può avere un costruttore con dei parametri richiesti per eseguire il parser del file XML. Inoltre si possono utilizzare dei flag booleani in corrispondenza dell'elemento iniziale (startElement) e uno StringBuffer per le ggere interamente il contenuto dell'elemento XML identificato. Il file scaricabile in questo link è un esempio di parser per un XML file tipo questo:


<ASC>
<AscTransl>
	<Code>A00</Code>
	<URI>http://aims.fao.org/aos/agrovoc/c_203</URI>
</AscTransl>
<AscTransl>
	<Code>A01</Code>
	<URI>http://aims.fao.org/aos/agrovoc/c_203</URI>
</AscTransl>
<AscTransl>
	<Code>A50</Code>
	<URI>http://aims.fao.org/aos/agrovoc/c_8679</URI>
</AscTransl>
<AscTransl>
	<Code>B00</Code>
	<URI>http://aims.fao.org/aos/agrovoc/c_3230</URI>
	<URI>http://aims.fao.org/aos/agrovoc/c_3635</URI>
</AscTransl>
</ASC>