Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate all XML node generations in java DOM

Tags:

java

dom

xml

I want to check to see if an XML document contains a 'person' element anywhere inside. I can check all the first-generation elements very simply:

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
  }
}

And and I can add more loops to go into subelements, but I would have to know how many nested loops to put in to determine how far into the document to drill. I could nest 10 loops, and end up with a person element nested 12 elements deep in a given document. I need to be able to pull out the element not matter how deeply nested it is.

Is there way to harvest elements from an entire document? Like return the text values of all tags as an array or iterate over it?

Something akin to python's elementtree 'findall' method perhaps:

for person in tree.findall('//person'):
   personlist.append(person)
like image 892
directedition Avatar asked Jun 23 '09 17:06

directedition


People also ask

What is NodeList in Java?

The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. The items in the NodeList are accessible via an integral index, starting from 0.


2 Answers

As mmyers states, you could use recursion for this problem.

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);
        }
    }
}
like image 85
user125661 Avatar answered Sep 30 '22 16:09

user125661


I see three possiblities (two of which others have answered):

  1. Use recursion.
  2. Use XPath (might be a bit overkill for this problem, but if you have a lot of queries like this it is definitely something to explore). Use kdgregory's help on that; a quick look at the api indicated that it is a bit painful to use directly.
  3. If what you have is in fact a Document (that is if root is a Document), you can use Document.getElementsByTagName
like image 38
Kathy Van Stone Avatar answered Sep 30 '22 17:09

Kathy Van Stone