Parsing XML in Java con SAX

Le tecnologie XML si sono affermate in molti ambiti, dallo scambio dati tra diverse piattaforme, grazie anche ad HTTP e WebService, alla messagistica. Anche da parte di Java, si è sentita sempre più impellente, quindi, la possibilità alla conversione di un documento XML in oggetti Java e viceversa, vediamone un esempio con l’uso di SAX.
Un programmatore che volesse utilizzare XML come formato dati della propria applicazione si troverà ad affrontare le seguenti problematiche:

  • Verificare la correttezza formale del documento XML ed eventualmente vederne la validità rispetto allo schema XML dettato dal DTD.
  • Analizzare il documento XML per isolare i suoi elementi o tag.
  • Rendere disponibili i contenuti di un documento XML all’applicazione Java.

Un documento XML è rappresentato da un struttura gerarchica ad albero, i cui elementi, identificati da alcuni tag, sono i nodi dell’albero e l’inclusione di un elemento dentro un’altro rappresenta la relazione padre-figlio tra nodo e nodo. I parser sono oggetti in grado di analizzare questo albero ed eventualmente manipolarlo, si suddividono in validanti e non validanti ed in altre categorie che ne determinano l’appartenenza. In questo articolo vedremo un esempio con un Event-Driven, basato su SAX API 2 ed in questo caso l’albero viene attraversato generando un evento ad ogni apertura o chiusura di un tag.
Scriviamo il nostro database XML (staff.xml):

<?xml version="1.0"?>
<company>
   <staff>
      <firstname>Bianchi</firstname>
      <lastname>Vittorio</lastname>
      <nickname>bvitt73</nickname>
      <salary>34000</salary>
   </staff>
   <staff>
      <firstname>Rossi</firstname>
      <lastname>Mario</lastname>
      <nickname>mariotto34</nickname>
      <salary>28000</salary>
   </staff>
</company>

SAX (Simple API for XML) è un tipo di parser che legge il file XML dall’inizio alla fine, come uno stream di dati ed ogni qualvolta incontra un elemento XML lo notifica all’applicazione. La notifica avviene mediante l’invocazione dei metodi specificati nell’interfaccia javax.sax.ContentHandler. Ad esempio quando un parser SAX incontra un elemento “<” durante la lettura di un documento XML, invoca il metodo callback startElement(), quindi invoca characters() e poi quando trova il simbolo “>” invoca il metodo endElement(). Costruiamo allora la nostra classe che ci consente di gestire i nostri dati dello staff:

package corso;

import org.xml.sax.*;
import org.xml.sax.helpers.*;

public class StaffSAX extends DefaultHandler
{
    boolean bfname = false;
    boolean blname = false;
    boolean bnname = false;
    boolean bsalary = false;

    public void startElement(String uri, String localName,
         String gName, Attributes attributes) throws SAXException
    {
      System.out.println("Elemento Iniziale: " + gName);
      if (gName.equalsIgnoreCase("firstname"))
         bfname = true;
      if (gName.equalsIgnoreCase("lastname"))
         blname = true;
      if (gName.equalsIgnoreCase("nickname"))
         bnname = true;
      if (gName.equalsIgnoreCase("salary"))
         bsalary = true;
    }

    public void endElement(String uri, String localName,
         String gName) throws SAXException
    {
      System.out.println("Elemento Finale: " + gName);
    }

    public void characters(char ch[], int start, int length)
         throws SAXException
    {
       if (bfname)
       {
          System.out.println("Cognome: " + new String(ch, start, length));
          bfname = false;
       }
       if (blname)
       {
          System.out.println("Nome: " + new String(ch, start, length));
          blname = false;
       }
       if (bnname)
       {
          System.out.println("Nickname: " + new String(ch, start, length));
          bnname = false;
       }
       if (bsalary)
       {
          System.out.println("Salario E." + new String(ch, start, length));
           bsalary = false;
       }
     }
}

Una volta definita la classe che gestisce gli eventi prodotti dal parser, basterà fare questi passaggi:

  1. Instanziare la classe handler.
  2. Instanziare la class Factory di SAX per avere applicazioni Java conformi allo standard XML.
  3. Invocare il metodo newSAXParser della Factory di SAX.
  4. Fare il parsing del documento XML e attribuire l’handler.

Ecco il codice:

package corso;

import javax.xml.parsers.*;

public class Main
{
    public static void main(String[] args)
    {
        try
        {
            StaffSAX handler = new StaffSAX();
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            parser.parse("staff.xml", handler);

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Come avete potuto notare è abbastanza semplice scrivere un programma che elabori un database in formato XML in Java mediante un parser SAX. I vantaggi derivanti dall’uso di un tale tipo di parser possono essere così riassunti:

  • Moderato utilizzo della memoria.
  • Velocità di esecuzione.
  • Semplicità di accesso ai dati contenuti nel file XML.

Magari se siete interessati, in futuro possiamo anche parlare di altri metodi di parsing di documenti XML in Java, per ora fermiamoci qui.

Pubblicato
Categorie: Java Taggato

Di Giampaolo Rossi

Sviluppatore software da oltre 16 anni.

2 commenti

  1. Ciao!
    Stavo cercando un esempio riassuntivo/tecnico/pratico per analizzare un file XML e questo tuo post è perfetto per rinfrescarmi la memoria sull’argomento.

    Siccome pero’ sono un rompiscatole ( 😉 ) , volevo farti notare che nel listato del parser il nome del metodo non è ‘EndElement’ ma ‘endElement’ altrimenti non viene mai riconosciuta la chiusura del tag.

    Ciao & grazie per l’articolo

I commenti sono chiusi.