2

I am trying to access some values in an XML document with Dom parser and I am getting a strange null pointer exception error. the code I am using is:

    import java.io.File;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;

    public class readXML {

    public static void main(String[] args) {
    File file = new File("C:\\Users\\manolaki\\Desktop\\assets.xml");
    try {
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document doc = builder.parse(file);
      doc.getDocumentElement().normalize();

            Node node = doc.getElementsByTagName("assets").item(0).getChildNodes().item(1).getChildNodes().item(1).getAttributes().getNamedItem("src");

            String boo = node.getNodeValue();

            System.out.println("Name is " + boo);

      }
    catch (Exception e) {
      e.printStackTrace();
      }
   }
}

the xml I am Using:

 <?xml version="1.0" encoding="UTF-8"?>
<xml>

<assets>
<sprite>
    <img src="menu.png"/>
</sprite>
<sprite>
    <img src="background.png"/>
</sprite>
<sprite>
    <img src="buttons.png"/>
</sprite>
<sprite>
    <img src="animals.png"/>
</sprite>
<sprite>
    <img src="cycles.png"/>
</sprite> 
<sprite>
    <img src="texts.mp3"/>
</sprite>
<sprite>
    <img src="music.mp3"/>
</sprite>
<sprite>
    <img src="click.mp3"/>
</sprite>
<sprite>
    <img src="swipe.mp3"/>
</sprite>
<sprite>
    <img src="dog.mp3"/>
</sprite>
</assets>

<assets>
<sprite>
    <img src="mehnu.png"/>
</sprite>
<sprite>
    <img src="background.png"/>
</sprite>
<sprite>
    <img src="buttons.png"/>
</sprite>
<sprite>
    <img src="animals.png"/>
</sprite>
<sprite>
    <img src="cycles.png"/>
</sprite> 
<sprite>
    <img src="texts.mp3"/>
</sprite>
<sprite>
    <img src="music.mp3"/>
</sprite>
<sprite>
    <img src="click.mp3"/>
</sprite>
<sprite>
    <img src="swipe.mp3"/>
</sprite>
<sprite>
    <img src="dog.mp3"/>
</sprite>
 </assets>

 </xml>

The code works fine as is and it prints out "menu.png" at the console. The problem is that while I can navigate through the assets nodes using the first "Item()" part, if i try to change the second "item()" to navigate through the sprites it prints a null pointer exception error. for example it works if I use:

                Node node = doc.getElementsByTagName("assets").item(1).getChildNodes().item(1).getChildNodes().item(1).getAttributes().getNamedItem("src");

but not when I use

            Node node = doc.getElementsByTagName("assets").item(0).getChildNodes().item(2).getChildNodes().item(1).getAttributes().getNamedItem("src");

Which I think is kind of strange.. given that eclipse is not finding any errors. any help would be appreciated. thanks

3
  • mb problem is in getElementsByTagName("assets").item(0) ? try item(1) instead of item(0) Commented Apr 14, 2014 at 12:06
  • split your chained calls into several lines to see which method call actually triggers the NPE Commented Apr 14, 2014 at 12:11
  • I Just noticed that it works only for odd numbers.. for example item(1) prints menu.png, item(3) prints "background.png, item(5) prints "buttons.png" etc. It prints NPE error when I use even numbers 2,4,6 etc.. any idea why? Commented Apr 14, 2014 at 12:52

1 Answer 1

1

Your problem is that item(0) of the NodeList is a text node, and text nodes don't have child nodes which is where your NullPointerException is being thrown.

Try adding this to your code to verify:

Node child0 = doc.getElementsByTagName("assets").item(0).getChildNodes().item(0);
if (child0.getNodeType() == Node.TEXT_NODE) {
    System.out.println("child node is text");
}

So just keep in mind that you need to check the type of each node when iterating through a NodeList.

In your case, your odd numbered children are text nodes and your even children are elements. Try this:

NodeList nodes = doc.getElementsByTagName("assets").item(0).getChildNodes();
for ( int x = 0; x < nodes.getLength(); x++ ) {
    Node node = nodes.item(x);
    if (node.getNodeType() == Node.TEXT_NODE) {
        System.out.println(x + " text");
    } else if (node.getNodeType() == Node.ELEMENT_NODE) {
        String nodeName = node.getNodeName();

        System.out.println(x + " Node: " + nodeName);
    }
}

Output:

0 text
1 Node: sprite
2 text
3 Node: sprite
4 text
5 Node: sprite
...

You might want to check out this article from Dr. Dobb's which has some good example code from which you could create some convenience methods for low level DOM parsing like this.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok that solves the mystery with the odd numbers. It turns out that when I use even numbers I get a text node while with odd numbers I get the actual node. I am not sure why exactly it works this way but at least I understand now and can work around it. I will also check the article for more insight. Thanks
This is because of the whitespace in your xml formatting. If you were to strip out the extra whitespace between nodes, you would get elements on both odd and even items. So don't just depend on odd vs. even!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.