/* * Copyright 2011 Luke Usherwood. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package net.bettyluke.tracinstant.data; import java.util.Iterator; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * A class to reduce the verbosity of pulling data out of a DOM. * * NOTE: Why do I get the feeling XML-Pull parser is what's wanted instead? I.e. when only * reading XML. Shame I don't have an Internet connection to read up on that right now :-) */ public class DOMUtils { /** * A little bridge between DOM methods and Java 5/6 Iterators, to help write * simple parsers concisely. (For situations where TreeWalker and NodeIterator * might be considered overkill.) */ private static final class ChildIterator <E extends Node> implements Iterable<E>, Iterator<E> { private final Class<E> m_Clazz; private E m_Next; /** * An iterator that iterates all children of a given type * @param typeToMatch Only Nodes of this type are considered. * @param elem The element containing the children to iterate. */ public ChildIterator(Class<E> typeToMatch, Element elem) { m_Clazz = typeToMatch; advance(elem.getFirstChild()); } @Override public Iterator<E> iterator() { return this; } @Override public boolean hasNext() { return m_Next != null; } @Override public E next() { E next = m_Next; advance(next.getNextSibling()); return next; } @Override public void remove() { throw new UnsupportedOperationException(); } private void advance(Node node) { while (node != null && !m_Clazz.isInstance(node)) { node = node.getNextSibling(); } m_Next = m_Clazz.cast(node); } } public static Iterable<Node> iterateChildNodes(Element elem) { return new ChildIterator<>(Node.class, elem); } public static Iterable<Element> iterateChildElements(Element elem) { return new ChildIterator<>(Element.class, elem); } public static Element findFirstChildElement(Element elem) { ChildIterator<Element> iter = new ChildIterator<>(Element.class, elem); return iter.hasNext() ? iter.next() : null; } public static Element findFirstChildElementNamed(Element elem, String tagName) { for (Element child : iterateChildElements(elem)) { if (tagName.equals(child.getTagName())) { return child; } } return null; } }