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

Schreibe einen Kommentar