Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我不能删除子元素I';我刚找到?没有找到错误_Java_Xml_Removechild_Getelementsbytagname - Fatal编程技术网

Java 为什么我不能删除子元素I';我刚找到?没有找到错误

Java 为什么我不能删除子元素I';我刚找到?没有找到错误,java,xml,removechild,getelementsbytagname,Java,Xml,Removechild,Getelementsbytagname,我正在构建一个脚本,它必须修补XML文件,包括用另一个元素替换一个元素列表。以下函数将修补程序(可能涉及同名元素的空列表)应用到父元素的同名元素列表(也可能是空列表)上。(这只是修补逻辑的一小部分) 为什么,当我运行代码时,会出现以下错误 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.s

我正在构建一个脚本,它必须修补XML文件,包括用另一个元素替换一个元素列表。以下函数将修补程序(可能涉及同名元素的空列表)应用到父元素的同名元素列表(也可能是空列表)上。(这只是修补逻辑的一小部分)

为什么,当我运行代码时,会出现以下错误

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行标记如下。)据我所知,我刚刚验证了元素是否存在(因为NodeList是活动的,它的第一个条目将始终是下一个匹配项或null)。有趣的是,这并不总是一个问题

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();
    }
}

这是因为当您执行parent.removeChild(节点)时,parent不一定是节点的父节点,因为getElementsByTagName()正在执行递归搜索。

parent.removeChild(节点)
正在抛出未找到错误,因为
节点
不是
父节点的子节点。我看到
节点
来自
getElementsByTagName
,它可能不是
父节点
的直接子节点。根据@Maurice和@fahd的诊断,它可能在父母的任何地方

你就不能先设定一个条件吗

parent.removeChild(node);
比如

if (parent.isSameNode(node.getParentNode()))
然后它将只删除给定父级的直接子级。

如何

nodeToBeRemoved.getParentNode().removeChild(nodeToBeRemoved);

谢谢你们两位。是否有一个非递归版本-
getChildNodes()
并实现我自己的名字搜索?我对java的XML库了解得越多,我发现它做的事情就越少。我想你必须实现自己的搜索这似乎是最好的解决方案。我实现了一个返回
列表
的函数,因为在我的例子中,我也不想看到
节点列表
的“活动”行为(由于我不能在这里发布代码块,所以在我的问题的末尾添加)。我想它会起作用-很不幸,效率很低。这并不能回答这个问题。若要评论或要求作者澄清,请在其帖子下方留下评论。确实如此,这一行需要位于514-您使用getElementsByTagName找到一个节点,然后使用getParentNode API将其从其父节点删除
nodeToBeRemoved.getParentNode().removeChild(nodeToBeRemoved);