Почему я не могу удалить детский элемент, который я только что нашел? Not_found_err.

StackOverflow https://stackoverflow.com/questions/3719384

Вопрос

Я строю скрипт, который должен исправлять файлы 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 маркируется ниже.) Насколько я понимаю, я только что проверил, что элемент существует (потому что odelist живет, его первая запись всегда будет следующим спичком или нулевым). Интересно, что это не всегда проблема.

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;
}
Это было полезно?

Решение

Это потому, что когда вы делаете Parent.removechild (узел), родитель не обязательно является родителем узла, потому что getelementsByTagname () делает рекурсивный поиск.

Другие советы

как насчет

nodeToBeRemoved.getParentNode().removeChild(nodeToBeRemoved);

parent.removeChild(node) выбрасывает not_found_err, потому что node не ребенок parent. Отказ я вижу это node происходит от getElementsByTagName что может быть не ближему ребенку parent. Отказ Это может быть где-нибудь под parent.

Здание на диагноз от @maurice и @fahd ...

Вы не можете просто положить условие до

parent.removeChild(node);

Такие как

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

Тогда он только удалит прямой ребенок данного родителя.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top