org.w3c.dom.Node.insertBefore:NullPointerException,Bug?

时间:2012-01-17 10:14:50

标签: java android xml dom android-xml

Android-SDK的org.w3c.dom.Node.insertBefore说明如下:

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.

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

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! 对我来说,这似乎是一个错误。任何人都可以确认/复制吗?


//编辑(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时,抛出上面显示的Exception。

所以相同的代码在普通的Java中工作,但在Android中不起作用。对我来说,似乎它仍然是org.w3c.dom的apache和实现中的一个错误。还有其他想法吗?

3 个答案:

答案 0 :(得分:3)

即使用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是否为空,因此refChildImpl.document!=document会引发NullPointerException 如果跟随正确

,这种实现没有任何意义

Android-SDK的org.w3c.dom.Node.insertBefore说明如下:

  

public abstract Node insertBefore(Node newChild,Node refChild)

     

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

答案 1 :(得分:0)

在if语句中添加doc!=null。看来你的doc对象是null。

答案 2 :(得分:0)

解决方法。需要answer by ljupce确认它是旧版Android中的错误。

由于node.insertBefore(newChild, null)不起作用,但与node.appendChild(newChild)相同,因此解决方法是在您以其他方式调用appendChild()时调用insertBefore() null refChild参数。

示例:

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

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