Emilio Emilio - 7 months ago 20
Java Question

Getting XML Node text value with Java DOM

I can't fetch text value with

Node.getNodeValue()
,
Node.getFirstChild().getNodeValue()
or with
Node.getTextContent()
.

My XML is like

<add job="351">
<tag>foobar</tag>
<tag>foobar2</tag>
</add>


And I'm trying to get tag value (non-text element fetching works fine). My Java code sounds like

Document doc = db.parse(new File(args[0]));
Node n = doc.getFirstChild();
NodeList nl = n.getChildNodes();
Node an,an2;

for (int i=0; i < nl.getLength(); i++) {
an = nl.item(i);

if(an.getNodeType()==Node.ELEMENT_NODE) {
NodeList nl2 = an.getChildNodes();

for(int i2=0; i2<nl2.getLength(); i2++) {
an2 = nl2.item(i2);

// DEBUG PRINTS
System.out.println(an2.getNodeName() + ": type (" + an2.getNodeType() + "):");

if(an2.hasChildNodes())
System.out.println(an2.getFirstChild().getTextContent());

if(an2.hasChildNodes())
System.out.println(an2.getFirstChild().getNodeValue());

System.out.println(an2.getTextContent());
System.out.println(an2.getNodeValue());
}
}
}


It prints out

tag type (1):
tag1
tag1
tag1
null
#text type (3):
_blank line_
_blank line_
...


Thanks for the help.

Answer

I'd print out the result of an2.getNodeName() as well for debugging purposes. My guess is that your tree crawling code isn't crawling to the nodes that you think it is. That suspicion is enhanced by the lack of checking for node names in your code.

Other than that, the javadoc for Node defines "getNodeValue()" to return null for Nodes of type Element. Therefore, you really should be using getTextContent(). I'm not sure why that wouldn't give you the text that you want.

Perhaps iterate the children of your tag node and see what types are there?

Tried this code and it works for me:

String xml = "<add job=\"351\">\n" +
             "    <tag>foobar</tag>\n" +
             "    <tag>foobar2</tag>\n" +
             "</add>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes());
Document doc = db.parse(bis);
Node n = doc.getFirstChild();
NodeList nl = n.getChildNodes();
Node an,an2;

for (int i=0; i < nl.getLength(); i++) {
    an = nl.item(i);
    if(an.getNodeType()==Node.ELEMENT_NODE) {
        NodeList nl2 = an.getChildNodes();

        for(int i2=0; i2<nl2.getLength(); i2++) {
            an2 = nl2.item(i2);
            // DEBUG PRINTS
            System.out.println(an2.getNodeName() + ": type (" + an2.getNodeType() + "):");
            if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getTextContent());
            if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getNodeValue());
            System.out.println(an2.getTextContent());
            System.out.println(an2.getNodeValue());
        }
    }
}

Output was:

#text: type (3): foobar foobar
#text: type (3): foobar2 foobar2