0

This is the XML file I'm working on:

<book>
    <chapter index="1" name="Chapter 2">
        <verse index="1" text="First Line" />
        <verse index="2" text="Second Line" />
        <verse index="3" text="Third Line" />
    </chapter>
    <chapter index="1" name="Chapter 2">
        <verse index="1" text="First Line" />
        <verse index="2" text="Second Line" />
        <verse index="3" text="Third Line" />
    </chapter>
</book>

This is what I desperately tried, following an answer posted: How can I read Xml attributes using Java?

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;


public class Main
{
    public static void main (String[] args)
    {
        try
        {
            File fXmlFile = new File("book.xml");
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
             Document doc = dBuilder.parse(fXmlFile);
             doc.getDocumentElement().normalize();

             System.out.println("Verse: " +
                     doc.getDocumentElement().getElementsByTagName("chapter").item(0).getChildNodes().item(0).getAttributes().getNamedItem("text").getNodeValue());

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

I tried to print the first verse of each chapter, but got a Null Pointer exception

1
  • 1
    A stack trace would be useful, if you could add it to your question. Commented Aug 15, 2014 at 16:41

4 Answers 4

2

The API you're using treats the whitespaces between the tags as seperate nodes. If you print the node names of child nodes of the first chapter using this code:

NodeList lst = doc.getDocumentElement().getElementsByTagName("chapter").item(0).getChildNodes();

for (int i = 0; i < lst.getLength(); i++) {
    System.out.println(lst.item(i).getNodeName());
}

you'll get:

#text
verse
#text
verse
#text
verse
#text

Which means that the node at index 0 is not the verse node, but a text node, that contains no attributes, which causes a NPE, since you try to call a method of the non existent attribute object (null).

If you delete the whitespaces before the verse node like this:

<book>
    <chapter index="1" name="Chapter 2"><verse index="1" text="First Line" />
...

, everything works fine.

But you better use getElementsByTagName("verse") to get the verse nodes, that are child nodes of the chapter:

System.out.println("Verse: "
                    + ((Element)doc.getDocumentElement().getElementsByTagName("chapter").item(0)).getElementsByTagName("verse").item(0).getAttributes().getNamedItem("text").getNodeValue());
Sign up to request clarification or add additional context in comments.

Comments

1

you may choose the possibility of using dom4j. its quite straight forward

Straight from dom4j

   public void treeWalk(Document document) {
        treeWalk( document.getRootElement() );
    }

    public void treeWalk(Element element) {
        for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
            Node node = element.node(i);
            if ( node instanceof Element ) {
                treeWalk( (Element) node );
            }
            else {
                // do something....
            }
        }
    }

then all you need to do is choosing attributes by adding a condition such as :

 ....
 if ( node instanceof Element ) {
    //condition goes here:: e.g.
    if(node.getParent().getName().equals("chapter") && node.getName().equals("verse"){
       if (node.attribute("index").getData().toString().equals("1"))
          System.out.println(node.attribute(text).getDate().toString());
    }
    treeWalk( (Element) node );
 }

output:

First Line
First Line

Comments

0

You can read it like this to read first verse of each chapter:

         NodeList chapters = doc.getElementsByTagName("chapter");

         for(int i=0;i < chapters.getLength();i++) {
             Element chapter = (Element) chapters.item(i);
             System.out.println("Chapter = " + chapter.getAttribute("name"));
             Element verse = (Element) chapter.getElementsByTagName("verse").item(0);
             System.out.println(verse.getAttribute("text"));
         }

Comments

0
NodeList listOfChapter = doc.getElementsByTagName("chapter");

NodeList listofVerse = doc.getDocumentElement().getElementsByTagName("chapter").item(0).getChildNodes(); 

for (int j = 0; j < listOfChapter.getLength(); j++) {
    for (int i = 0; i < listofVerse.getLength() / listOfChapter.getLength(); i++) {
        Element chapter = (Element) listOfChapter.item(j);
        System.out.println("Chapter = " + chapter.getAttribute("name"));
        System.out.println("Index: " + ((Element) doc.getDocumentElement().getElementsByTagName("chapter").item(j)).getElementsByTagName("verse").item(i).getAttributes().getNamedItem("index").getNodeValue());
        System.out.println("Verse: " + ((Element) doc.getDocumentElement().getElementsByTagName("chapter").item(j)).getElementsByTagName("verse").item(i).getAttributes().getNamedItem("text").getNodeValue());
    }
}

2 Comments

Output: run: Chapter = Chapter 2 Index: 1 Verse: First Line Chapter = Chapter 2 Index: 2 Verse: Second Line Chapter = Chapter 2 Index: 3 Verse: Third Line Chapter = Chapter 3 Index: 1 Verse: First Line Chapter = Chapter 3 Index: 2 Verse: Second Line Chapter = Chapter 3 Index: 3 Verse: Third Line
Please add an explanation to your answer, as code-only answers cannot improve the askers comprehension on the topic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.