56

I am new to XML. I want to read the following XML on the basis of request name. Please help me on how to read the below XML in Java -

<?xml version="1.0"?>
    <config>
        <Request name="ValidateEmailRequest">
            <requestqueue>emailrequest</requestqueue>
            <responsequeue>emailresponse</responsequeue>
        </Request>
        <Request name="CleanEmail">
            <requestqueue>Cleanrequest</requestqueue>
            <responsequeue>Cleanresponse</responsequeue>
        </Request>
    </config>
1

10 Answers 10

75

If your XML is a String, Then you can do the following:

String xml = ""; //Populated XML String....

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xml)));
Element rootElement = document.getDocumentElement();

If your XML is in a file, then Document document will be instantiated like this:

Document document = builder.parse(new File("file.xml"));

The document.getDocumentElement() returns you the node that is the document element of the document (in your case <config>).

Once you have a rootElement, you can access the element's attribute (by calling rootElement.getAttribute() method), etc. For more methods on java's org.w3c.dom.Element

More info on java DocumentBuilder & DocumentBuilderFactory. Bear in mind, the example provided creates a XML DOM tree so if you have a huge XML data, the tree can be huge.


Update Here's an example to get "value" of element <requestqueue>

protected String getString(String tagName, Element element) {
        NodeList list = element.getElementsByTagName(tagName);
        if (list != null && list.getLength() > 0) {
            NodeList subList = list.item(0).getChildNodes();

            if (subList != null && subList.getLength() > 0) {
                return subList.item(0).getNodeValue();
            }
        }

        return null;
    }

You can effectively call it as,

String requestQueueName = getString("requestqueue", element);
Sign up to request clarification or add additional context in comments.

5 Comments

Why not use the built in Java SE XPath library? stackoverflow.com/questions/4076910/…
@Blaise Doughan, you could. I just used DOM to support legacy java that are still active out there.
Fair enough, if someone is still on JDK 1.4 then your approach is reasonable. If they are on 1.5 or later then the javax.xml.xpath library is much easier. I hate to see people doing things the hard way when a better way exists.
@Blaise Doughan, you will be surprised at how many companies (most especially banks) still run JDK 1.4.
Agreed there are developers using JDK 1.4, and that your solution is appropriate to JDK 1.4. If, however they are using JDK 1.5 or above the javax.xml.xpath library is more appropriate. There are many developers with JDK 1.5 and 1.6 as baselines.
38

In case you just need one (first) value to retrieve from xml:

public static String getTagValue(String xml, String tagName){
    return xml.split("<"+tagName+">")[1].split("</"+tagName+">")[0];
}

In case you want to parse whole xml document use JSoup:

Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
for (Element e : doc.select("Request")) {
    System.out.println(e);
}

6 Comments

thanks for pointing to jsoup - vanilla java is pain in the ass here
Using first approach but getting ArrayOutOfBound exception
very efficient solution.
The first solution will behave incorrectly if input xml has <![CDATA[ blocks.
@Klesun Saying that it will behave incorrectly a bit bold IMHO. It will return the content of the tag regardless of what is inside the tag. What do you expect it to do?
|
29

If you are just looking to get a single value from the XML you may want to use Java's XPath library. For an example see my answer to a previous question:

It would look something like:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class Demo {

    public static void main(String[] args) {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = domFactory.newDocumentBuilder();
            Document dDoc = builder.parse("E:/test.xml");

            XPath xPath = XPathFactory.newInstance().newXPath();
            Node node = (Node) xPath.evaluate("/Request/@name", dDoc, XPathConstants.NODE);
            System.out.println(node.getNodeValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

6 Comments

Required Node found NodeList on Node node = (NodeList) xPath.evaluate("/Request/@name", dDoc, XPathConstants.NODE);
can we achieve the same using JAXB?Will it be better than this approach?
Why are you casting to a NodeList but assigning it to a Node?
@RajeevM - It was a typo, it's fixed now.
@ziggy, XPath never existed in JDK 1.4.
|
5

There are a number of different ways to do this. You might want to check out XStream or JAXB. There are tutorials and the examples.

1 Comment

@sam: And you probably want to check this SO question as well, stackoverflow.com/questions/1558087/xstream-or-simple.
4

If the XML is well formed then you can convert it to Document. By using the XPath you can get the XML Elements.

String xml = "<stackusers><name>Yash</name><age>30</age></stackusers>";

Form XML-String Create Document and find the elements using its XML-Path.

Document doc = getDocument(xml, true);

    public static Document getDocument(String xmlData, boolean isXMLData) throws Exception {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        dbFactory.setNamespaceAware(true);
        dbFactory.setIgnoringComments(true);
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc;
        if (isXMLData) {
            InputSource ips = new org.xml.sax.InputSource(new StringReader(xmlData));
            doc = dBuilder.parse(ips);
        } else {
            doc = dBuilder.parse( new File(xmlData) );
        }
        return doc;
    }

Use org.apache.xpath.XPathAPI to get Node or NodeList.

System.out.println("XPathAPI:"+getNodeValue(doc, "/stackusers/age/text()"));

NodeList nodeList = getNodeList(doc, "/stackusers");
System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList));
System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList.item(0)));

    public static String getNodeValue(Document doc, String xpathExpression) throws Exception {
        Node node = org.apache.xpath.XPathAPI.selectSingleNode(doc, xpathExpression);
        String nodeValue = node.getNodeValue();
        return nodeValue;
    }
    public static NodeList getNodeList(Document doc, String xpathExpression) throws Exception {
        NodeList result = org.apache.xpath.XPathAPI.selectNodeList(doc, xpathExpression);
        return result;
    }

Using javax.xml.xpath.XPathFactory

System.out.println("javax.xml.xpath.XPathFactory:"+getXPathFactoryValue(doc, "/stackusers/age"));

    static XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
    public static String getXPathFactoryValue(Document doc, String xpathExpression) throws XPathExpressionException, TransformerException, IOException {
        Node node = (Node) xpath.evaluate(xpathExpression, doc, XPathConstants.NODE);
        String nodeStr = getXmlContentAsString(node);
        return nodeStr;
    }

Using Document Element.

System.out.println("DocumentElementText:"+getDocumentElementText(doc, "age"));

    public static String getDocumentElementText(Document doc, String elementName) {
        return doc.getElementsByTagName(elementName).item(0).getTextContent();
    }

Get value in between two strings.

String nodeVlaue = org.apache.commons.lang.StringUtils.substringBetween(xml, "<age>", "</age>");
System.out.println("StringUtils.substringBetween():"+nodeVlaue);

Full Example:

public static void main(String[] args) throws Exception {
    String xml = "<stackusers><name>Yash</name><age>30</age></stackusers>";
    Document doc = getDocument(xml, true);
    
    String nodeVlaue = org.apache.commons.lang.StringUtils.substringBetween(xml, "<age>", "</age>");
    System.out.println("StringUtils.substringBetween():"+nodeVlaue);
    
    System.out.println("DocumentElementText:"+getDocumentElementText(doc, "age"));
    System.out.println("javax.xml.xpath.XPathFactory:"+getXPathFactoryValue(doc, "/stackusers/age"));
    
    System.out.println("XPathAPI:"+getNodeValue(doc, "/stackusers/age/text()"));
    NodeList nodeList = getNodeList(doc, "/stackusers");
    System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList));
    System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList.item(0)));
}
public static String getXmlContentAsString(Node node) throws TransformerException, IOException {
    StringBuilder stringBuilder = new StringBuilder();
    NodeList childNodes = node.getChildNodes();
    int length = childNodes.getLength();
    for (int i = 0; i < length; i++) {
        stringBuilder.append( toString(childNodes.item(i), true) );
    }
    return stringBuilder.toString();
}

OutPut:

StringUtils.substringBetween():30
DocumentElementText:30
javax.xml.xpath.XPathFactory:30
XPathAPI:30
XPathAPI NodeList:<stackusers>
   <name>Yash</name>
   <age>30</age>
</stackusers>
XPathAPI NodeList:<name>Yash</name><age>30</age>

Comments

1

following links might help

http://labe.felk.cvut.cz/~xfaigl/mep/xml/java-xml.htm

http://developerlife.com/tutorials/?p=25

http://www.java-samples.com/showtutorial.php?tutorialid=152

Comments

1

There are two general ways of doing that. You will either create a Domain Object Model of that XML file, take a look at this

and the second choice is using event driven parsing, which is an alternative to DOM xml representation. Imho you can find the best overall comparison of these two basic techniques here. Of course there are much more to know about processing xml, for instance if you are given XML schema definition (XSD), you could use JAXB.

Comments

1

There are various APIs available to read/write XML files through Java. I would refer using StaX

Also This can be useful - Java XML APIs

Comments

1

You can make a class which extends org.xml.sax.helpers.DefaultHandler and call

start_<tag_name>(Attributes attrs);

and

end_<tag_name>();

For it is:

start_request_queue(attrs);

etc.

And then extends that class and implement xml configuration file parsers you want. Example:

  ...
  public void startElement(String uri, String name, String qname,
                           org.xml.sax.Attributes attrs) 
                  throws org.xml.sax.SAXException {
    Class[] args = new Class[2];
    args[0] = uri.getClass();
    args[1] = org.xml.sax.Attributes.class;
    try {
      String mname = name.replace("-", "");
      java.lang.reflect.Method m = 
            getClass().getDeclaredMethod("start" + mname, args);
      m.invoke(this, new Object[] { uri, (org.xml.sax.Attributes)attrs }); 
    }
catch (IllegalAccessException e) { throw new RuntimeException(e); }
catch (NoSuchMethodException e) { throw new RuntimeException(e); }
catch (java.lang.reflect.InvocationTargetException e) { org.xml.sax.SAXException se = new org.xml.sax.SAXException(e.getTargetException()); se.setStackTrace(e.getTargetException().getStackTrace()); }

and in a particular configuration parser:

   public void start_Request(String uri, org.xml.sax.Attributes attrs) {
     // make sure to read attributes correctly
     System.err.println("Request, name="+ attrs.getValue(0);
   }

Comments

1

Since you are using this for configuration, your best bet is apache commons-configuration. For simple files it's way easier to use than "raw" XML parsers.

See the XML how-to

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.