12
    try {
        String data = "<a><b c='d' e='f'>0.15</b></a>";
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
                .newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory
                .newDocumentBuilder();
        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(data));
        Document document = documentBuilder.parse(is);

        NodeList nl = document.getElementsByTagName("b");
        Node n = (Node) nl.item(0);
        System.out.println(n.getNodeValue());
    } catch (Exception e) {
        System.out.println("Exception " + e);

    }

I am expecting it to print 0.15, but it prints null. Any Ideas?

Edit: This did the trick

        if (n.hasChildNodes())
            System.out.println(n.getFirstChild().getNodeValue());
        else 
            System.out.println(n.getNodeValue());

6 Answers 6

11

That's because an element in fact has no nodeValue. Instead it has a text node as a child, which has the nodeValue you want.

In short, you'll want to getNodeValue() on the first child of the element node.

Sometimes the element contains multiple text nodes, as they do have a maximum size, in which case you'll need something á la this, from the page linked earlier:

public static String getNodeValue(Node node) {
    StringBuffer buf = new StringBuffer();
    NodeList children = node.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        Node textChild = children.item(i);
        if (textChild.getNodeType() != Node.TEXT_NODE) {
            System.err.println("Mixed content! Skipping child element " + textChild.getNodeName());
            continue;
        }
        buf.append(textChild.getNodeValue());
    }
    return buf.toString();
}
Sign up to request clarification or add additional context in comments.

1 Comment

Good explanation, and thanks much for the excellent function. Works like a champ.
7

Try extracting it from the Element rather than from the Node:

try {
    String data = "<a><b c='d' e='f'>0.15</b></a>";
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
            .newInstance();
    DocumentBuilder documentBuilder = documentBuilderFactory
            .newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(data));
    Document document = documentBuilder.parse(is);

    NodeList nl = document.getElementsByTagName("b");
    Element el = (Element) nl.item(0);
    Text elText = (Text) el.getFirstChild();
    String theValue = elText.getNodeValue();
    System.out.println(theValue);
} catch (Exception e) {
    System.out.println("Exception " + e);
}

1 Comment

@mkal - I just edited to output the nodevalue instead of the Text instance!
3
System.out.println(n.getFirstChild().getNodeValue());

Comments

2
 private String getTextValue(Element element, String string) {
    String textVal = null;
    NodeList nl = element.getElementsByTagName(string);
    if(nl != null && nl.getLength() > 0) {
        Element el = (Element)nl.item(0);
        textVal = el.getFirstChild().getNodeValue();
    }

    return textVal;

}

Comments

1

If the node has no further nested descendants, than n.getTextContent() works quite well.

Comments

1

You could use jOOX as a wrapper for standard DOM, to simplify your code.

String data = "<a><b c='d' e='f'>0.15</b></a>";
String value = $(data).find("b").text();

You could also have jOOX convert that value to double, for instance:

Double value = $(data).find("b").text(Double.class);

Comments

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.