Org.w3c.dom.Node.insertBefore: NullPointerException, error?

Description of org.w3c.dom.Node.insert Before 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 a 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!
This seems like a mistake to me. Can anyone confirm / reproduce this?


// edit (01/18/2012 13:05):
I created a new java project because I wanted to know if this worked 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 just fine.

I also created a new Android project for retesting:

 @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 insertBefore, the Exception above is thrown.

So, the same code works in regular Java, but not in Android. It still seems to me that this is a mistake in implementing apache org.w3c.dom approval. Any other ideas?

+6
source share
3 answers

It can be reproduced even with 4.1.2 Implementation for insertBefore from 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); } 

As you can see, no one checks to see if refChildImpl is null, so refChildImpl.document!=document throws NullPointerException This implementation makes no sense if the following is true.

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

public abstract Node insertBefore (Node newChild, Node refChild)

Inserts a Node newChild in front of an existing Node refChild child. If refChild is null, insert newChild at the end of the list of children.

+3
source

Add doc!=null to the if statement. Your doc object seems to be null.

0
source

Workaround. Needed , as ljupce's answer confirms it in older versions of Android.

Since node.insertBefore(newChild, null) does not work, but it matches node.appendChild(newChild) , a workaround for appendChild() is to simply call appendChild() if you would otherwise call insertBefore() with a null refChild parameter.

Example:

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

Source: https://habr.com/ru/post/906190/


All Articles