2009-06-23 22 views
7

Quiero comprobar si un documento XML contiene un elemento 'persona' en cualquier lugar dentro. Puedo comprobar todos los elementos de primera generación muy simple:Iterar todas las generaciones de nodos XML en DOM 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 
    } 
} 

Y y puedo añadir más bucles para entrar en sub-elementos, pero que tendría que saber cuántos bucles anidados para poner en determinar hasta qué punto en el documento para perforar. Pude anidar 10 bucles y terminar con un elemento de persona anidado 12 elementos en un documento determinado. Necesito poder sacar el elemento, sin importar cuán profundamente anidado esté.

¿Hay forma de cosechar elementos de un documento completo? ¿Como devolver los valores de texto de todas las etiquetas como una matriz o iterar sobre ella?

Algo parecido a pitón de elementtree 'findall' quizá método:

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

creo que es necesario http://en.wikipedia.org/wiki/Recursion_%28computer_science % 29. –

Respuesta

10

Como mmyers Unidos, usted podría usar recursividad para este 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

veo tres posibilidades (dos de los cuales otros han respondido):

  1. Use recursión.
  2. Utilice XPath (podría ser un poco exagerado para este problema, pero si tiene un lote de consultas como este, es definitivamente algo para explorar). Usa la ayuda de kdgregory para eso; una vista rápida de en la API indicó que es un poco doloroso usar directamente.
  3. Si lo que tienes es en realidad un Document (es decir, si root es una Document), puede utilizar Document.getElementsByTagName
+1

+1 - # 3 es definitivamente el enfoque más simple – kdgregory

+0

+1 para el 3er enfoque – NemoStein

0

Aparte de Document.getElementsByTagName() o XPath, también se puede utilizar jOOX, una biblioteca que he creado para una manipulación y acceso XML más simple. jOOX envuelve las API estándar de Java y agrega jquery -como métodos de utilidad. El fragmento de código Python se traduciría a este código 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

Aquí está la versión formateada:

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"); 
     } 
    } 
} 
Cuestiones relacionadas