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

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和实现中的一个错误。 还有其他想法吗?

它甚至可以通过4.1.0实现从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 throws NullPointerException如果以下是正确的,那么这个实现没有任何意义

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

public abstract Node insertBefore(Node newChild,Node refChild)

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

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

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

由于node.insertBefore(newChild, null)不起作用,但与node.appendChild(newChild)相同,因此解决方法是在没有使用null refChild参数调用insertBefore()时调用appendChild()

例:

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