Java org.w3c.dom.Node.insertBefore:NullPointerException,Bug?
Android SDK的org.w3c.dom.Node.insertBefore描述如下:Java org.w3c.dom.Node.insertBefore:NullPointerException,Bug?,java,android,xml,dom,android-xml,Java,Android,Xml,Dom,Android Xml,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 &
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);
WARN/System.err(11029):位于org.apache.harmony.xml.dom.InnerNodeImpl.insertBefore(InnerNodeImpl.java:86)
我用安卓2.2和安卓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实现中的一个bug。还有其他想法吗?添加
doc=if语句中的null
。您的文档对象似乎为空。即使使用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=文档
throwsNullPointerException
如果以下内容正确,则此实现没有任何意义
Android SDK的说明如下所示:
公共抽象节点insertBefore(节点newChild、节点refChild)
在现有子节点refChild之前插入节点newChild。如果
refChild为空,请在子项列表的末尾插入newChild
解决方法。需要,因为确认这是旧版本Android中的一个bug 由于不起作用,但与相同,因此解决方法是在使用null
refChild
参数调用insertBefore()
时,只需调用appendChild()
例如:
// Before
node.insertBefore(newChild, refChild);
// After
if (refChild != null)
node.insertBefore(newChild, refChild);
else
node.appendChild(newChild);
我加了博士=null,但我得到相同的异常。我很确定这是一个bug,因为如果一个节点提供了一个有效的节点作为第二个参数,那么整个代码都会工作。我将添加此文档=在我的原始文章中也进行空检查,以便其他读者清楚地看到。我打赌这是您的代码,而不是库。认识到问题出在你身上是一个漫长而艰难的教训。当然,这可能是我的错。这就是为什么我先在这里问这个问题(在我提交bug之前),然后请求帮助或其他人复制这个问题。但这并不是我在android中使用apache harmony实现org.w3c.dom时遇到的第一个问题——在实现过程中还存在其他缺陷或漏洞,这些缺陷或漏洞已经被开发人员确认,并使我的生活更加艰难。所以也许a有一些偏见^^