Home   |   Archivio   |   Chi siamo   |   Contatti
Filomena Pallone
Occhiello
JDOM Visita iterativa di un documento Xml
di
Filomena Pallone
Ancora JDOM: metodi ricorsivi per visitare l’alberatura di un file XML.

JDOM Visita iterativa di un documento Xml

di Filomena Pallone filpal@yahoo.it

Introduzione

JDOM è un buon compromesso tra DOM e SAX: non crea la struttura dell’intero documento residente in memoria come DOM e non genera eventi, come SAX, dove lo sviluppatore deve intercettarli; bensì tiene memoria della struttura del documento e non del contenuto rendendo facile e veloce la creazione di un parser a doc per i propri documenti XML.

Il documento Xml visto come una struttura gerarchica

Si prenda come riferimento il seguente documento XML:

<?xml version="1.0"?>
<CLIENTI>
 <CLIENTE NOME ="Maria" COGNOME="Rossi">
  <INDIRIZZO VIA="Roma" NUM_CIVICO="20" CAP="00100">
   <CITTA>Roma</CITTA>
   <STATO>Italia</STATO>
  </INDIRIZZO>
 </CLIENTE>
 <CLIENTE NOME ="Mario" COGNOME="Bianchi">
  <INDIRIZZO VIA="A.Manzoni" NUM_CIVICO="106" CAP="00140">
   <CITTA>Milano</CITTA>
   <STATO>Italia</STATO>
  </INDIRIZZO>
 </CLIENTE>
 <CLIENTE NOME ="Antonio" COGNOME="Alberti">
  <INDIRIZZO VIA="G. Garibaldi" NUM_CIVICO="549" CAP="00170">
   <CITTA>Napoli</CITTA>
   <STATO>Italia</STATO>
  </INDIRIZZO>
 </CLIENTE>
</CLIENTI>

Il documento può essere visto come una struttura gerarchica, dove la root è CLIENTI, il livello sottostante è costituito da tutti gli elementi CLIENTE, ed infine l’ultimo livello costituito dagli elementi INDIRIZZO CITTA STATO. Con una semplice operazione è possibile ottenere la lista degli elementi al livello sottostante della root:

List clienti = doc.getRootElement().getChildren();

e per ogni cliente è possibile ottenere tutti i suoi elementi:

for(Iterator i = children.iterator(); i.hasNext();) {

    Element current = (Element)i.next();

    List childrenElement = current.getChildren();

}

A questo punto è chiaro l’organizzazione gerarchica a livelli che utilizza JDOM per un documento XML.

Per semplificare la ricerca

Ritornando alla lista dei clienti, se si vuole ottenere la città in cui risiede il primo cliente della lista basterà scrivere un metodo iterativo, senza preoccuparsi a quale livello il tag <CITTA> si trovi:

public Element getElement(String key, List e) {
Element elem = null;

if(!(e.isEmpty())) {

    for(Iterator i = e.iterator(); i.hasNext();) {

        Element current = (Element)i.next();

        String name = current.getName();

        if(name.equalsIgnoreCase(key)) {

            elem = current;

            break;

        } else {

            List subListE = current.getChildren();

            if(!(subListE.isEmpty())) {

                getElement(key, subListE);
// chiamata ricorsiva
            }

        }

    }

}

return elem;

}

e richiamarlo

Element città = getElement(“citta”, doc.getRootElement().getChildren());

Nel caso in cui si vorrebbe ottenere tutte le città a cui appartengono i clienti, basterà utilizzare il seguente metodo:

public List getElements(String key, List in, List out) {
if(!(in.isEmpty())) {

    for(Iterator i = in.iterator(); i.hasNext();) {

        Element current = (Element)i.next();

        String name = current.getName();

        if(name.equalsIgnoreCase(key)) {

            out.add(current);

        } else {

            List subListE = current.getChildren();

            getElements(key, subListE, out);
// chiamata ricorsiva
        }

    }

}

return out;

}

Generalizzare innanzitutto: Elementi ed Attributi

A volte può succedere che lo stesso tag possa essere un Elemento in un documento, ed essere Attributo in un altro documento: prendiamo come esempio il tag <CAP>, nel precedente documento appare come Attributo:

<INDIRIZZO VIA="Roma" NUM_CIVICO="20" CAP="00100">

ma potrebbe essere Elemento, del tipo:

<INDIRIZZO> <VIA>Roma</VIA> <NUM_CIVICO>20</NUM_CIVICO> <CAP>00100</CAP>
    </INDIRIZZO>

entrambi i documenti possono essere processati dallo stesso parser implementando un metodo del tipo:

public String getValueKey(String key, Element e) {
    String trovata = null;

    Attribute a = e.getAttribute(key);

    if(a != null) {

        trovata = a.getValue();

    } else {

        List listE = e.getChildren();

        if(!(listE.isEmpty())) {

            for(Iterator i = listE.iterator(); i.hasNext();) {

                Element current = (Element)i.next();

                if(current.getName().equals(key)) {

                    trovata = current.getTextTrim();

                    break;

                }

                if((trovata == null) && (current != null)) {

                    getValueKey(key, current);
// chiamata ricorsiva
                }

            }

        }

    }

    return trovata;

}

Questo metodo restituirà il valore del primo Attributo o Elemento cercato; con la stessa tecnica utilizzata in precedenza non sarà difficile farsi restituire una lista (Elementi o Attributi) del valore cercato.

Conclusioni

Con questi esempi si è voluto dare una chiara spiegazione di come sia possibile visitare un documento XML in modo semplice ed immediato, offrendo anche la possibiltà di slegarsi dalla natura del tag cercato: nei documenti ben strutturati si potrà cercare i dati voluti senza preoccuparsi se siano “Elementi” o “Attributi”, organizzandoli in Liste, Array o altre strutture dati.

Bibliografia

  • [1] JDOM - http://www.jdom.org
  • [2] MokaByte - "Manuale pratico di Java", HOPS Libri
  • [3] Wes Biggs, Harry Evans - "Simplify XML Programming with JDOM", IBM developerWorks
  • [biografia autore] Filomena Pallone è nata a Cosenza ne 1975; ha conseguito il diploma di laurea in “Ingegneria Informatica ed Automatica” presso L’Università degli Studi della Calabria, di Cosenza. Attualmente lavora a Roma nella progettazione e nella programmazione object oriented.
MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it