2009-06-23 12 views
7

Voglio verificare se un documento XML contiene un elemento 'persona' ovunque all'interno. Posso controllare tutti gli elementi di prima generazione in modo molto semplice:Iterare tutte le generazioni di nodi XML in java DOM

NodeList nodeList = root.getChildNodes(); 
for(int i=0; i<nodeList.getLength(); i++){ 
    Node childNode = nodeList.item(i); 
    if (childNode.getNodeName() == "person") { 
    //do something with it 
    } 
} 

E e posso aggiungere ulteriori cicli di andare in sottoelementi, ma avrei dovuto sapere quanti cicli annidati per mettere in per determinare quanto lontano nel documento da trapanare. Potrei annidare 10 loop e finire con un elemento person annidato 12 elementi in profondità in un determinato documento. Devo essere in grado di estrarre l'elemento, non importa quanto profondamente sia annidato.

C'è modo di raccogliere elementi da un intero documento? Come restituire i valori di testo di tutti i tag come un array o iterare su di esso?

qualcosa di simile al di pitone elementtree 'findall' metodo forse:

for person in tree.findall('//person'): 
    personlist.append(person) 
+1

Penso che è necessario http://en.wikipedia.org/wiki/Recursion_%28computer_science % 29. –

risposta

10

Come mmyers afferma, è possibile utilizzare la ricorsione per questo problema.

doSomethingWithAll(root.getChildNodes()); 

void doSomethingWithAll(NodeList nodeList) 
{ 
    for (int i = 0; i < nodeList.getLength(); i++) { 
     Node childNode = nodeList.item(i); 
     if (childNode.getNodeName().equals("person")) { 
      //do something with it 
     } 

     NodeList children = childNode.getChildNodes(); 
     if (children != null) 
     { 
      doSomethingWithAll(children); 
     } 
    } 
} 
10

Vedo tre possiblities (due dei quali altri hanno risposto):

  1. Utilizzare la ricorsione.
  2. Utilizzare XPath (potrebbe essere un po 'eccessivo per questo problema, ma se si dispone di una quantità di query come questa è sicuramente qualcosa da esplorare). Usa l'aiuto di kdgregory su quello; a una rapida occhiata all'API ha indicato che è un po 'doloroso utilizzare direttamente .
  3. Se quello che hai è in realtà un Document (cioè se root è un Document), è possibile utilizzare Document.getElementsByTagName
+1

+1 - # 3 è sicuramente l'approccio più semplice – kdgregory

+0

+1 per il terzo approccio – NemoStein

0

parte Document.getElementsByTagName() o XPath, si potrebbe anche usare jOOX, una biblioteca che ho creato per semplificare l'accesso e la manipolazione XML. jOOX esegue il wrapping delle API Java standard e aggiunge i metodi di utilità jquery -like. Il tuo codice Python frammento di allora si traducono in questo codice Java:

// Just looking for tag names 
for (Element person : $(tree).find("person")) { 
    personlist.append(person); 
} 

// Use XPath for more elaborate queries 
for (Element person : $(tree).xpath("//person")) { 
    personlist.append(person); 
} 
2

Ecco la versione formattata:

Element root = xmlData.getDocumentElement(); 
NodeList children = root.getChildNodes(); 

public void doSomethingWithAllToConsole(NodeList nodeList, String tabs) 
{ 
    for(int i=0; i<nodeList.getLength(); i++){ 

     //print current node & values 
     Node childNode = nodeList.item(i); 
     if(childNode.getNodeType()==Node.ELEMENT_NODE){ 
      System.out.print(tabs + childNode.getNodeName()); 
      if(childNode.getFirstChild()!=null 
        && childNode.getFirstChild().getNodeType()==Node.TEXT_NODE 
        && !StringUtil.isNullOrEmpty(childNode.getFirstChild().getNodeValue())){ 
       System.out.print(" = " + childNode.getFirstChild().getNodeValue()); 
      } 
      System.out.println(); 
     } 

     //recursively iterate through child nodes 
     NodeList children = childNode.getChildNodes(); 
     if (children != null) 
     { 
      doSomethingWithAllToConsole(children, tabs+"\t"); 
     } 
    } 
} 
Problemi correlati