如果當前DOM元素在迭代NodeList(通過getElementsByTagName()和其他元素創建)時被刪除(通過JavaScript),元素將從NodeList中消失。這使得NodeList的正確迭代更加棘手。
public class IteratableNodeList implements Iterable<Node> {
final NodeList nodeList;
public IteratableNodeList(final NodeList _nodeList) {
nodeList = _nodeList;
}
@Override
public Iterator<Node> iterator() {
return new Iterator<Node>() {
private int index = -1;
private Node lastNode = null;
private boolean isCurrentReplaced() {
return lastNode != null && index < nodeList.getLength() &&
lastNode != nodeList.item(index);
}
@Override
public boolean hasNext() {
return index + 1 < nodeList.getLength() || isCurrentReplaced();
}
@Override
public Node next() {
if (hasNext()) {
if (isCurrentReplaced()) {
// It got removed by a change in the DOM.
lastNode = nodeList.item(index);
} else {
lastNode = nodeList.item(++index);
}
return lastNode;
} else {
throw new NoSuchElementException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public Stream<Node> stream() {
Spliterator<Node> spliterator =
Spliterators.spliterator(iterator(), nodeList.getLength(), 0);
return StreamSupport.stream(spliterator, false);
}
}
然後使用它是這樣的: new IteratableNodeList(doc.getElementsByTagName(elementType)). stream().filter(...)
或者: new IteratableNodeList(doc.getElementsByTagName(elementType)).forEach(...)
您不能對NodeList使用foreach循環,因爲它沒有實現Iterable接口。只有選項,您可以使用nodeList.getLength使用for或while循環。 http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/NodeList.html –
雖然這是與你問的問題相切,但我會避開使用w3c來自Java標準庫的東西。國際海事組織這是一個熱門的混亂,有更好的XML解析庫在那裏。 – Jazzepi
+ Jazzepi我知道這是一個老話題,但是您建議使用哪種XML解析庫?注意這個w3c庫沒有提供一個簡單而通用的迭代器的事實是一個「細節」,但看起來像是針對這個東西的多一個參數(即使選擇一個庫可能比這個更復雜)。 –