org.w3c.dom.Node.insertBefore:NullPointerException,错误?

发布于 2024-12-27 13:10:18 字数 2379 浏览 3 评论 0原文

Android-SDK 的 org.w3c.dom.Node.insertBefore 的描述如下:

public abstract Node insertBefore (Node newChild, Node refChild)
在现有子节点 refChild 之前插入节点 newChild。 如果 refChild 为 null,则在子级列表的末尾插入 newChild。

但是,如果我执行以下操作,则会在 insertBefore 实现中出现 NullPointerException:

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

警告/System.err(11029):位于 org.apache.harmony.xml.dom.InnerNodeImpl.insertBefore(InnerNodeImpl.java:86)

我在 Android 2.2 和 Android 2.3.3 上尝试过此操作!
对我来说这似乎是一个错误。有人可以确认/复制吗?


//编辑 (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 中运行。对我来说,这似乎仍然是 org.w3c.dom 的 apache Harmony 实现中的一个错误。还有其他想法吗?

The description of org.w3c.dom.Node.insertBefore of the Android-SDK say the following:

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

But if I do the following I get NullPointerException that occurs in the insertBefore implementation:

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)

I tried this with Android 2.2 and Android 2.3.3!
For me it seems to be a bug. Can anybody confirm/reproduce that?

//edit (18.01.2012 13:05):
I created a new java-project, because I wanted to see if this works in a java application:

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

This code works perfectly.

I also created a new android project to test this again:

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

When the application reaches the insertBefore, the Exception shown above is thrown.

So the same code works in normal Java, but not in Android. For me it still seems that it is a bug in the apache harmony implementation of org.w3c.dom. Any other ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

‖放下 2025-01-03 13:10:18

即使用4.1.2也可以重现
org.apache.harmony.xml.dom 中 insertBefore 的实现

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 是否为 null,因此 refChildImpl.document!=document 会抛出 空指针异常
如果以下正确,此实现没有任何意义

org.w3c 的描述Android-SDK 的 .dom.Node.insertBefore 内容如下:

公共抽象节点insertBefore(节点newChild,节点refChild)

在现有子节点 refChild 之前插入节点 newChild。如果
refChild 为 null,将 newChild 插入到子级列表的末尾。

It can be reproduced even with 4.1.2
Implementation for insertBefore from org.apache.harmony.xml.dom is

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

As you can see no one checks if refChildImpl is null so refChildImpl.document!=document throws NullPointerException
This implementation does not make any sense if following is correct

The description of org.w3c.dom.Node.insertBefore of the Android-SDK says the following:

public abstract Node insertBefore (Node newChild, Node refChild)

Inserts the node newChild before the existing child node refChild. If
refChild is null, insert newChild at the end of the list of children.

孤寂小茶 2025-01-03 13:10:18

在 if 语句中添加 doc!=null。看来您的 doc 对象为空。

Add doc!=null in the if statement. It seems your doc object is null.

提赋 2025-01-03 13:10:18

解决方法。需要,因为ljupce的回答确认这是旧版本Android中的一个错误。

由于 node.insertBefore(newChild, null) 不起作用,但与 < code>node.appendChild(newChild),解决方法是在本应调用 insertBefore() 时简单地调用 appendChild()带有 null refChild 参数。

例子:

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

// After
if (refChild != null)
    node.insertBefore(newChild, refChild);
else
    node.appendChild(newChild);

Workaround. Needed since answer by ljupce confirms it's a bug in older versions of Android.

Since node.insertBefore(newChild, null) doesn't work, but is the same as node.appendChild(newChild), the workaround is to simply call appendChild() when you would otherwise have called insertBefore() with a null refChild parameter.

Example:

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

// After
if (refChild != null)
    node.insertBefore(newChild, refChild);
else
    node.appendChild(newChild);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文