Why can I not remove a child element I've just found? NOT_FOUND_ERR

爷,独闯天下 提交于 2019-11-30 21:58:43

问题


I'm building a script which has to patch XML files, including replacing one list of elements with another. The following function applies a patch (involving a possibly empty list of elements with the same name) onto a parent Element's list of elements by the same name (also possibly an empty list). (This is only a small part of the patching logic).

Why, when I run the code, do I get the following error?

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)

(Line 514 is labelled below.) As far as I understand it, I've just verified that the element exists (because NodeList is live, its first entry will always be the next match or null). Interestingly, this isn't always a 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: I used the following function as a replacement for getElementsByTagName() (see accepted answer).

/** 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;
}

回答1:


This is because when you are doing parent.removeChild(node), parent is not necessarily the parent of the node because getElementsByTagName() is doing a recursive search.




回答2:


how about

nodeToBeRemoved.getParentNode().removeChild(nodeToBeRemoved);



回答3:


parent.removeChild(node) is throwing a NOT_FOUND_ERR because node is not a child of parent. I see that node comes from getElementsByTagName which might not be an immediate child of parent. It could be anywhere under parent.




回答4:


Building on the diagnosis by @Maurice and @fahd...

Can't you just put a condition before

parent.removeChild(node);

such as

if (parent.isSameNode(node.getParentNode()))

Then it would only remove a direct child of the given parent.



来源:https://stackoverflow.com/questions/3719384/why-can-i-not-remove-a-child-element-ive-just-found-not-found-err

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!