我正在構建一個腳本,它必須修補XML文件,包括用另一個元素替換一個元素列表。以下函數通過相同的名稱(也可能是一個空列表)將一個補丁(涉及一個可能爲空的元素名稱相同的列表)應用到父元素的元素列表中。 (這只是修補邏輯的一小部分)。爲什麼我不能刪除剛發現的子元素? NOT_FOUND_ERR
爲什麼當我運行代碼時,是否會出現以下錯誤?
org.w3c.dom.DOMException: NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist.
at com.sun.org.apache.xerces.internal.dom.ParentNode.internalRemoveChild(ParentNode.java:503)
at com.sun.org.apache.xerces.internal.dom.ParentNode.removeChild(ParentNode.java:484)
at CombineSweeps$PTReplaceNodeList.apply(CombineSweeps.java:514)
(514線如下標記)。據我瞭解,我只是證實該元件存在(因爲節點列表是活的,它的第一個條目將永遠是下一場比賽或空)。有趣的是,這並不總是一個問題。
private static class PTReplaceNodeList extends PTBase {
private final String name;
private final String nextElement;
private final List<Node> childList;
...
int apply(Document document, Node parent, Node node_unused) {
NodeList nodes;
// A marker for where to insert our nodes.
// We make a guess using nextElement (if null, means at end).
Node refNode = null;
if (parent instanceof Document) { // root element
Document parDoc = (Document) parent;
nodes = parDoc.getElementsByTagName(name);
if (nextElement != null) {
refNode = parDoc.getElementsByTagName(nextElement).item(0);
}
} else {
Element parElt = (Element) parent;
nodes = parElt.getElementsByTagName(name);
if (nextElement != null) {
refNode = parElt.getElementsByTagName(nextElement).item(0);
}
}
while (true) {
// iterate through the list of nodes
Node node = nodes.item(0);
if (node == null) {
break;
}
// Reliable guess: insert before node following last in list
refNode = node.getNextSibling();
parent.removeChild(node); // line 514
}
for (Node child : childList) {
Node imported = document.importNode(child, true);
parent.insertBefore(imported, refNode);
}
return childList.size();
}
}
編輯:我用以下函數替代getElementsByTagName()
(請參閱接受的答案)。
/** Returns all direct children of node with name name.
*
* Note: not the same as getElementsByTagName(), which finds all descendants. */
static List<Node> getChildNodes(Node node, String name){
ArrayList<Node> r = new ArrayList<Node>();
NodeList children = node.getChildNodes();
int l = children.getLength();
for(int i = 0; i < l; ++i){
if(name.equals(children.item(i).getNodeName()))
r.add(children.item(i));
}
return r;
}
感謝你們倆。是否有一個非遞歸版本 - 「getChildNodes()'並實現我自己的名稱搜索?也許?我對java的XML庫瞭解得越多,我發現它就越不像我期望的那樣。 – dhardy 2010-09-15 19:04:17
我想你將不得不實施自己的搜索 – 2010-09-15 19:21:32
這似乎是最好的解決方案。我實現了一個返回'List'的函數,因爲在我的情況下,我也並不真的希望NodeList的「實時」行爲(在我的問題結尾添加,因爲我無法在此處發佈代碼塊)。 –
dhardy
2010-09-16 08:20:25