2
        File fXmlFile = new File(path);//path is a String
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document XMLbook = dBuilder.parse(fXmlFile);
        Node root = XMLbook.getFirstChild(); //(1)
        Node book = XMLbook.getElementsByTagName("BOOK").item(0);//(2)
        Node lastChapter=book.getLastChild();//(3)
        Node lastSubChapter=lastChapter.getLastChild(); //(4)
...
}

The problem is it reaches null at lastSubChapter so my program ends bad :( and i have no idea what i did wrong...the code seems okay.

Also, i don`t get what NULL represents: the node value?

  1. [ROOT: NULL ] - what i see when debugging
  2. [ BOOK: NULL]- what i see when debugging
  3. [ #text: ] - what i see when debugging - what does it mean?
  4. PROBLEM!! here lastSubChapter gets NULL :( why?

The XML file I am reading from is:

    <?xml version="1.0"?>
    <ROOT>
        <TITLE>Portocalia ca zapada</TITLE>
        <BOOK>
            <Chapter name="1">
                <Subchapter name="1.1">
                    <paragraph>Primul paragraf!</paragraph>
                </Subchapter>
            </Chapter>
            <Chapter name="2">
                <Subchapter name="2.1">
                    <paragraph>A fost o data ca niciodata</paragraph>
                </Subchapter>
                <Subchapter name="2.2">
                    <paragraph>In luna a13a ea s-a maritat.</paragraph>
                </Subchapter>
                <Subchapter name="2.3">
                    <paragraph>In continuare, bineinteles</paragraph>
                    <paragraph>asa cum se intampla in toate povestile</paragraph>
                </Subchapter>
            </Chapter>
        </BOOK>
    </ROOT>

I want to get the last node Subchapter, the one whose name is "2.3".

Is there another safer way i can get it?

M A
  • 71,713
  • 13
  • 134
  • 174
Lulu
  • 175
  • 1
  • 2
  • 12
  • Do you have any special reasons to use DOM? Can you use JAXB? – AlexR Nov 06 '14 at 16:56
  • And how would it look like? It is just a school project...i`ve used what i had found by searching on google... i`ve never worked with XMLs in Java before – Lulu Nov 06 '14 at 16:59
  • I would suggest SAX Parser for this type of xml data. Since,it's small and simple. SAX Parser will allow you to parse data by the Element(tag) Name. Very easy and simple to use. – Lokesh Nov 06 '14 at 17:03
  • the ROOT: null is just the string representation for the node. perhaps because there are no attributes, it shows null. I wouldn't worry about it – Joeblade Nov 06 '14 at 17:07
  • @Joeblade, it keeps being null even if the node has attribute. But if it`s not a reason to worry, then I won`t :D – Lulu Nov 06 '14 at 21:22

2 Answers2

4

The children of BOOK and Chapter also include whitespace (i.e. text content) due to the indentation of the XML contents. So the getLastChild is retrieving whitespace text instead of an element.

You can simply reach the elements via Element#getElementsByTagName and get the last node.

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document XMLbook = dBuilder.parse(fXmlFile);
Node root = XMLbook.getFirstChild(); //(1)
Node book = XMLbook.getElementsByTagName("BOOK").item(0);//(2)
NodeList chapterNodes = ((Element)book).getElementsByTagName("Chapter");
if(chapterNodes != null && chapterNodes.getLength() > 0) {
    Node chapterNode = chapterNodes.item(chapterNodes.getLength() - 1);
    NodeList subChapterNodes = ((Element)chapterNode).getElementsByTagName("Subchapter");
    if(subChapterNodes != null && subChapterNodes.getLength() > 0) {
        Node subChapterNode = subChapterNodes.item(subChapterNodes.getLength() - 1);
        System.out.println(subChapterNode.getNodeName());
    }
}
M A
  • 71,713
  • 13
  • 134
  • 174
-1

OK, as far as I understand you do not have limitation to use JAXB.

So start from creating model. Something like the following:

@XmlRootElement
class Root {
    @XmlElement
    private String title;
    @XmlElement
    private Book book;
}

@XmlRootElement
class Book {
    @XmlElement
    private List<Chapter> chapters;
}

@XmlRootElement
class Chapter {
  ....
}

etc, etc, ...

Add getters and setters yourself.

Now take a look on how to use JAXB:

How to serialize and de-serialize objects using JAXB?

Community
  • 1
  • 1
AlexR
  • 114,158
  • 16
  • 130
  • 208