2

I've written class to parse some xml into an object and it's not working correctly, when I try and get the value of a node I get a null rather than the contents of the node.

Here is a simplified version of my class that just does the xml parsing of a single node:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

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

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XmlReaderCutDown {

    private static Logger logger = Logger.getLogger(CtiButtonsXmlReader.class);

    public static void testXml(String confFile){
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(new File(confFile));
            doc.getDocumentElement().normalize();
            if (logger.isDebugEnabled()){
                logger.debug("The root element is " + doc.getDocumentElement().getNodeName());
            }

            NodeList rows =  doc.getElementsByTagName("row");

            NodeList topRowButtons = ((Element)rows.item(0)).getElementsByTagName("button");
            logger.debug("Top row has " +topRowButtons.getLength() + " items.");
            Node buttonNode = topRowButtons.item(0);

            NodeList nodeList = ((Element)buttonNode).getElementsByTagName("id");
            logger.debug("Node list count for "+ "id" + " = " + nodeList.getLength());
            Element element = (Element)nodeList.item(0);
            String xx = element.getNodeValue();
            logger.debug(xx);
            String elementValue = ((Node)element).getNodeValue();
            if (elementValue != null) {
                elementValue = elementValue.trim();
            }
            else {
                logger.debug("Value was null");
            }
            logger.debug("Node id = "+ elementValue);

        } catch (ParserConfigurationException e) {

            logger.fatal(e.toString(),e);
        } catch (SAXException e) {
            logger.fatal(e.toString(),e);
        } catch (IOException e) {
            logger.fatal(e.toString(),e);
        } catch (Exception e) {
            logger.fatal(e.toString(),e);
        }

    }


    public static void main(String[] args){
        DOMConfigurator.configure("log4j.xml");

        testXml("test.xml");
    }
}

And here is a stripped down version of my xml file:

<?xml version="1.0"?>
<root>
    <row>
        <button>
            <id>this is an id</id>
            <action>action</action>
            <image-src>../images/img.png</image-src>
            <alt-text>alt txt</alt-text>
            <tool-tip>Tool tip</tool-tip>
        </button>
    </row>
</root>

This is what the logging statments output:

DEBUG XmlReaderCutDown - The root element is root

DEBUG XmlReaderCutDown - Top row has 1 items.

DEBUG XmlReaderCutDown - Node list count for id = 1

DEBUG XmlReaderCutDown -

DEBUG XmlReaderCutDown - Value was null

DEBUG XmlReaderCutDown - Node id = null

Why isn't it getting the text in the xml node?

I'm running using JDK 1.6_10

1
  • Note if you want to try it out but dont have log4j then you can replace the logging statments with System.out.println(); Commented Jun 10, 2009 at 10:23

3 Answers 3

6

Because the element you get is the parent element of the text one, containing the text you need. To access the text of this element, you shall use getTextContent instead of getNodeValue.

For more information, see the table in the Node javadoc.

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

3 Comments

Thanks that works a charm, one question though why does the code on this page java-tips.org/java-se-tips/javax.xml.parsers/… work when it uses node value?
Because they get the first child of the element in question, which is the text node. It's globally the same thing that getTextContent does, only safer in the getTextContent case.
You can use nodeValue() on a Text node.
2

See http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/Node.html . Element.getNodeValue() always returns null. You should use Element.getTextContent()

Comments

1

Consider using XPath as an alternative to manually walking nodes:

  public static void testXml(String confFile)
      throws XPathExpressionException {
    XPathFactory xpFactory = XPathFactory.newInstance();
    XPath xpath = xpFactory.newXPath();

    NodeList rows = (NodeList) xpath.evaluate("root/row",
        new InputSource(confFile), XPathConstants.NODESET);

    for (int i = 0; i < rows.getLength(); i++) {
      Node row = rows.item(i);
      String id = xpath.evaluate("button/id", row);
      System.out.println("id=" + id);
    }
  }

  public static void main(String[] args)
      throws XPathExpressionException {
    testXml("test.xml");
  }

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.