org.w3c.dom.Node.insertBefore: NullPointerException, ошибка? - PullRequest
6 голосов
/ 17 января 2012

Описание org.w3c.dom.Node.insertBefore Android-SDK говорит следующее:

public abstract Node insertBefore (Node newChild, Node refChild) <br/> Inserts the node newChild before the existing child node refChild. <strong>If refChild is null, insert newChild at the end of the list of children.</strong>

Но если я сделаю следующее, я получу исключение NullPointerException, которое происходитв реализации insertBefore:

if(doc != null && doc.getFirstChild() != null && tmpNode != null)
    doc.getFirstChild().insertBefore(tmpNode, null);

WARN/System.err(11029): at org.apache.harmony.xml.dom.InnerNodeImpl.insertBefore(InnerNodeImpl.java:86)

Я пробовал это с Android 2.2 и Android 2.3.3!
Для меня это кажется ошибкой.Кто-нибудь может подтвердить / воспроизвести это?

// edit (18.01.2012 13:05):
Я создал новый java-проект, потому что хотел посмотреть, работает ли он в java-приложении:

public static void main(String[] args) {
    DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder;

        try {
            docBuilder = dbfac.newDocumentBuilder();
            Document d = docBuilder.newDocument();

            if(d != null){
                d.appendChild(d.createElement("root"));
                if(d.getFirstChild() != null){
                    d.getFirstChild().insertBefore(d.createElement("foo"), null);
                    System.out.println(d.getFirstChild().getFirstChild().getNodeName());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Этот код работает отлично.

Я также создал новый проект для Android, чтобы протестировать его снова:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder;

    try {
        docBuilder = dbfac.newDocumentBuilder();
        Document d = docBuilder.newDocument();

        if(d != null){
            d.appendChild(d.createElement("root"));
            if(d.getFirstChild() != null){
                d.getFirstChild().insertBefore(d.createElement("foo"), null);
                System.out.println(d.getFirstChild().getFirstChild().getNodeName());
            }
        }
    } catch (Exception e2) {
        e2.printStackTrace();
    }
}

Когда приложение достигает insertBefore, выдается исключение, показанное выше.

Так жекод работает в обычной Java, но не в Android.Мне все еще кажется, что это ошибка в реализации Apache Harmony в org.w3c.dom.Есть другие идеи?

Ответы [ 3 ]

3 голосов
/ 13 ноября 2012

Может воспроизводиться даже с 4.1.2 Реализация для insertBefore из org.apache.harmony.xml.dom:

public Node insertBefore(Node newChild, Node refChild) throws DOMException {
    LeafNodeImpl refChildImpl = (LeafNodeImpl) refChild;

    if (refChildImpl.document != document) {
        throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
    }

    if (refChildImpl.parent != this) {
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
    }

    return insertChildAt(newChild, refChildImpl.index);
}

Как видите, никто не проверяет, является ли refChildImpl нулевым, поэтому refChildImpl.document!=document бросает NullPointerException Эта реализация не имеет никакого смысла, если следующее правильно

Описание org.w3c.dom.Node.insertBefore Android-SDK гласит следующее:

открытый абстрактный Node insertBefore (Node newChild, Node refChild)

Вставляет узел newChild перед существующим дочерним узлом refChild. Если refChild имеет значение null, вставьте newChild в конец списка детей.

0 голосов
/ 13 июня 2018

Обходной путь. Необходим, поскольку ответ от ljupce подтверждает, что это ошибка в более старых версиях Android.

Поскольку node.insertBefore(newChild, null) не работает, но совпадает с node.appendChild(newChild), обходной путь - просто позвонить appendChild(), когда вы в противном случае вызвали бы insertBefore() с нулевым параметром refChild.

Пример:

// Before
node.insertBefore(newChild, refChild);

// After
if (refChild != null)
    node.insertBefore(newChild, refChild);
else
    node.appendChild(newChild);
0 голосов
/ 17 января 2012

Добавьте doc!=null в операторе if.Кажется, ваш объект документа является нулевым.

...