Warum kann ich nicht entfernen Sie ein child-element, die ich gerade gefunden habe? NOT_FOUND_ERR
Baue ich ein Skript, welches patch-XML-Dateien, einschließlich dem Austausch einer Liste von Elementen mit einem anderen. Die folgende Funktion wendet einen patch (mit einer möglicherweise leeren Liste von Elementen mit dem gleichen Namen) auf ein übergeordnetes Element in die Liste der Elemente mit dem gleichen Namen (ggf. auch eine leere Liste). (Dies ist nur ein kleiner Teil der Patch-Logik).
Warum, wenn ich den code auszuführen, bekomme ich folgende Fehler?
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)
(Zeile 514 ist unten gekennzeichnet.) Soweit ich es verstehe, ich habe gerade verifiziert, dass das element vorhanden ist (da NodeList ist live, deren erste Eintrag wird immer das nächste Spiel oder null). Interessanterweise ist dies nicht immer ein problem.
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();
}
}
Edit: ich habe folgende Funktion als Ersatz für getElementsByTagName()
(siehe Antwort akzeptiert).
/** 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;
}
InformationsquelleAutor der Frage dhardy | 2010-09-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist, weil, wenn Sie tun, Elternteil.removeChild(Knoten), ein Elternteil ist nicht notwendigerweise das übergeordnete Element des Knotens, da getElementsByTagName() ist eine rekursive Suche.
InformationsquelleAutor der Antwort Maurice Perry
wie etwa
InformationsquelleAutor der Antwort Kalpesh Soni
parent.removeChild(node)
wirft ein NOT_FOUND_ERR weilnode
ist kein Kind vonparent
. Ich sehe, dassnode
kommt ausgetElementsByTagName
die vielleicht nicht eine sofortige Kindparent
. Es könnte sein, überall unterparent
.InformationsquelleAutor der Antwort dogbane
Aufbauend auf die Diagnose von @Moritz und @fahd...
Können Sie nicht nur eine Bedingung, bevor
wie
Dann würde es nur dann entfernen, ein direktes Kind von den angegebenen Eltern.
InformationsquelleAutor der Antwort LarsH