001 /* JAPI - (Yet anothr (hopefully) useful) Java API
002 *
003 * Copyright (C) 2004-2006 Christian Hujer
004 *
005 * This program is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU General Public License as
007 * published by the Free Software Foundation; either version 2 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful, but
011 * WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013 * General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program; if not, write to the Free Software
017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018 * 02111-1307, USA.
019 */
020
021 package net.sf.japi.xml;
022
023 import java.util.Iterator;
024 import java.util.NoSuchElementException;
025 import javax.xml.xpath.XPath;
026 import static javax.xml.xpath.XPathConstants.NODESET;
027 import javax.xml.xpath.XPathExpressionException;
028 import org.w3c.dom.Element;
029 import org.w3c.dom.Node;
030 import static org.w3c.dom.Node.ELEMENT_NODE;
031 import org.w3c.dom.NodeList;
032
033 /** A combined iterable / iterator implementation for iterating over NodeLists.
034 * @author <a href="mailto:Christian.Hujer@itcqis.com">Christian Hujer</a>
035 */
036 public class NodeListIterator<T extends Node> implements Iterable<T>, Iterator<T> {
037
038 /** The NodeList to iterate over. */
039 private final NodeList nodeList;
040
041 /** Index of next element. */
042 private int index;
043
044 /** Convenience helper method for getting the first child of an element that is an element with a specific name.
045 * @param el element to get child of
046 * @param childName name of child element to get
047 * @return child element or <code>null</code> if no such child element
048 */
049 public static Element getFirstChild(final Element el, final String childName) {
050 final NodeList childNodes = el.getChildNodes();
051 final int count = childNodes.getLength();
052 for (int i = 0; i < count; i++) {
053 final Node node = childNodes.item(i);
054 if (node.getNodeType() == ELEMENT_NODE && node.getNodeName().equals(childName)) {
055 return (Element) node;
056 }
057 }
058 return null;
059 }
060
061 /** Create a NodeListIterator.
062 * @param nodeList NodeList to iterate over
063 */
064 public NodeListIterator(final NodeList nodeList) {
065 this.nodeList = nodeList;
066 }
067
068 /** Create a NodeListIterator.
069 * @param item Element to evaluate against
070 * @param nodeType node type of children
071 */
072 public NodeListIterator(final Element item, final short nodeType) {
073 this(new FilteredNodeList<T>(item, nodeType));
074 }
075
076 /** Create a NodeListIterator.
077 * @param item Element to evaluate against
078 * @param childName name of child element
079 */
080 public NodeListIterator(final Element item, final String childName) {
081 this(new FilteredNodeList<T>(item, childName));
082 }
083
084 /** Create a NodeListIterator.
085 * @param xpath XPath to evaulate against
086 * @param item Object to evaluate against
087 * @param expression XPath expression to evaluate
088 * @throws XPathExpressionException in case of xpath errors
089 */
090 public NodeListIterator(final XPath xpath, final Element item, final String expression) throws XPathExpressionException {
091 this((NodeList) xpath.evaluate(expression, item, NODESET));
092 }
093
094 /** {@inheritDoc} */
095 public Iterator<T> iterator() {
096 return this;
097 }
098
099 /** {@inheritDoc} */
100 public boolean hasNext() {
101 return index < nodeList.getLength();
102 }
103
104 /** {@inheritDoc} */
105 public T next() throws NoSuchElementException {
106 final T item = (T) nodeList.item(index++);
107 if (item == null) {
108 throw new NoSuchElementException();
109 }
110 return item;
111 }
112
113 /** {@inheritDoc} */
114 public void remove() {
115 throw new UnsupportedOperationException();
116 }
117
118 /** Get the number of elements this iterator would iterate over all.
119 * @return number of elements
120 */
121 public int size() {
122 return nodeList.getLength();
123 }
124
125 } // class NodeListIterator