PDA

Visualizza versione completa : [Java] Leggere file xml


GiulioCesare
16-12-2005, 22.54.05
Salve ragazzi, sto cercando di leggere un file xml, tramite java, ma ho dei problemi, ho fatto due metodi che leggono dalla radice del file, ed a secondo dell'element che viene passato leggono il relativo valore, però invece di ritornare il valore giusto, ritorna un valore nullo. Posto di seguito i due metodi che ho fatto, e poi il mio file xml da leggere, con la speranza che qualcuno mi aiuti

public String getParam(String paramname)
{
//get the root elememt
Element docEle = dom.getDocumentElement();
String retparam = null;
NodeList nl = docEle.getElementsByTagName("radice");

if(nl != null && nl.getLength() > 0)
{
for(int i = 0 ; i < nl.getLength();i++)
{
Element el = (Element)nl.item(i);
retparam = getTextValue(el,paramname);
}
}
return retparam;
}

public String getTextValue(Element ele, String tagName)
{
String textVal = null;
NodeList nl = ele.getElementsByTagName(tagName);
if(nl != null && nl.getLength() > 0)
{
Element el = (Element)nl.item(0);
textVal = el.getFirstChild().getNodeValue();
}
if(textVal.equals(null)) textVal = "";
return textVal;
}


File XML
<?xml version="1.0" encoding="UTF-8"?>
<radice>
<driver_db>Valore</driver_db>
<url_db>Valore</url_db>
<user_db>Valore</user_db>
<path_dest_xml>Valore</path_dest_xml>
<tipo_db>Valore</tipo_db>
</radice>

Dav82
17-12-2005, 02.04.15
Domani gli do un'occhiata, ora rischio di dirti cacchiate ;)

Dav82
17-12-2005, 03.02.50
Non ho sonno :S quindi rispondo :)


La variabile nl contiene zero elementi.
Con

Element docEle = dom.getDocumentElement();

prendi l'elemento radice del tuo file xml, che si chiama proprio "radice"... puoi verificarlo facendo


System.out.println("Nome = " + docEle.getTagName());


Quindi ti basta fare una


NodeList nl = docEle.getElementsByTagName("*");

per prendere tutti i figli di "radice" e poi ci fai quel che vuoi :)

In pratica docEle è già ciò che cercavi ("radice"), quindi al suo interno non trovavi "radice" stesso ;)

GiulioCesare
17-12-2005, 12.41.01
Ti ringrazio molto per l'aiuto, ho però ancora un problema facendo
docEle.getElementsByTagName("*"); non riesco poi a ciclare i vari figli, mi ritorna sempre un valore nullo, c'è un modo per avere accesso diretto ad un figlio della radice?

Dav82
17-12-2005, 14.10.01
Se usi lo stesso codice che c'è sopra, è giusto che non funzioni. Questo perchè in nl hai la NodeList degli elementi figli di "radice", ovvero i cinque nodi con tag "driver_db",
"url_db", "user_db", "path_dest_xml", "tipo_db". Con il ciclo for nel metodo getParam() cicli su questi elementi e fin qui tutto bene. Poi però, per ognuno di questi elementi, in getTextValue() prendi ancora i figli e di questi cerchi di prendere il valore: è qua l'errore, poichè questi cinque elementi non hanno figli.


Il metodo getElementsByTagName() prende già tutti gli elementi con un determinato nome (o tutti senza distinzione se si passa "*"), indipendentemente dalla profondità a cui si trovano :) E' in pratica un modo per creare una lista piatta di elementi, senza dover scrivere un metodo ricorsivo che fa una visita completa dell'albero.
Se per esempio nel tuo file xml aggiungi ad uno qualsiasi degli elementi alcuni elementi figli, e controlli il valore di nl.getLength(), vedi che questo è incrementato proprio del numero di elementi figli che hai aggiunto.

:)

Dav82
17-12-2005, 16.32.35
Per dire, io scriverei questo codice:


public static String[] getParam(String tagName, File file) throws org.xml.sax.SAXException,
IOException, javax.xml.parsers.ParserConfigurationException {

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.newDocument();

//costruisco il documento
dom = db.parse(file);

NodeList nl = dom.getElementsByTagName(tagName);
String[] result = new String[nl.getLength()];

for(int i = 0; i < nl.getLength(); i++) {
result[i] = nl.item(i).getFirstChild().getNodeValue();
}

return result;
}


Così eviti di prenderti tutti gli elementi che non ti servono, e ti pigli solo quello che ti interessa (ovviamente il file viene ugualmente parsato tutto in preorder). Ho messo un array di String (o un Vector, lì va a gusti e casi specifici) così il metodo è un po' più generico: se in un file hai due o più elementi con lo stesso nome, ti vengono restituiti i valori di tutti questi elementi, e non solo di uno a caso :)

GiulioCesare
17-12-2005, 17.43.08
Io ho trovato un'altra soluzione, la quale senza cicli cattura l'element di interesse, qualsiasi sia il suo livello nell'alberatura dell'xml, secondo te può essere la mia una buona soluzione?

public String getElement(String paramname)throws Exception
{
String retparam = null;
Element docEle = dom.getDocumentElement();
NodeList nl = docEle.getElementsByTagName(paramname);
Element el = (Element)nl.item(0);
retparam = el.getFirstChild().getNodeValue();
return retparam;
}

Dav82
17-12-2005, 18.00.35
E' quasi pari alla mia, solo senza cicli e escludendo dagli elementi presi in considerazione quello radice.

Se sei sicuro a priori che il file xml abbia, fra gli elementi che ti interessano, tutti elementi con tag differenti (come in questo caso, perchè il file xml lo fai tu, almeno penso), e che tu non debba prendere in esame l'elemento radice, va benissimo (Y)