javaxmldom

Can I iterate through a NodeList using for-each in Java?


I want to iterate through a NodeList using a for-each loop in Java. I have it working with a for loop and a do-while loop but not for-each.

NodeList nList = dom.getElementsByTagName("year");
do {
    Element ele = (Element) nList.item(i);
    list.add(ele.getElementsByTagName("MonthId").item(0).getTextContent());
    i++;
} while (i < nList.getLength());

NodeList nList = dom.getElementsByTagName("year");

for (int i = 0; i < nList.getLength(); i++) {
    Element ele = (Element) nList.item(i);
    list.add(ele.getElementsByTagName("MonthId").item(0).getTextContent());
}

Solution

  • The workaround for this problem is straight-forward, and, thankfully you have to implements it only once.

    import java.util.*;
    import org.w3c.dom.*;
    
    public final class XmlUtil {
      private XmlUtil() {
      }
    
      public static List<Node> asList(NodeList n) {
        return n.getLength() == 0 ? Collections.emptyList() :
                new NodeListWrapper(n);
      }
    
      static private final class NodeListWrapper extends AbstractList<Node>
              implements RandomAccess {
        private final NodeList list;
    
        NodeListWrapper(NodeList l) {
          list = l;
        }
    
        public Node get(int index) {
          final Node node = list.item(index);
    
          if (node != null) {
            return node;
          } else {
            throw new IndexOutOfBoundsException();
          }
        }
    
        public int size() {
          return list.getLength();
        }
      }
    }
    
    

    Once you have added this utility class to your project and added a static import for the XmlUtil.asList method to your source code you can use it like this:

    for(Node n: asList(dom.getElementsByTagName("year"))) {
      …
    }