Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read XML child node values by using a loop in java

Tags:

java

xml

Here is my xml code...

<flow>
    <TaskID>100</TaskID>
    <TaskID>101</TaskID>
    <TaskID>102</TaskID>
    <TaskID>103</TaskID>    
</flow>

I want to know how to get taskID values in a for loop in java. Please help me...

like image 712
Sagar Avatar asked Oct 26 '25 10:10

Sagar


2 Answers

DOM parser solution, fairly simple, no extra libraries required.

public static void main(String[] args) throws SAXException, IOException,
        ParserConfigurationException {

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();

    String input = "<outer>";
    input += "<otherstuff><TaskID>123</TaskID></otherstuff>";
    input += "<flow>";
    input += "<TaskID>100</TaskID>";
    input += "<TaskID>101</TaskID>";
    input += "<TaskID>102</TaskID>";
    input += "<TaskID>103</TaskID>";
    input += "</flow>";
    input += "</outer>";
    Document document = builder.parse(new InputSource(new StringReader(
            input)));

    NodeList flowList = document.getElementsByTagName("flow");
    for (int i = 0; i < flowList.getLength(); i++) {
        NodeList childList = flowList.item(i).getChildNodes();
        for (int j = 0; j < childList.getLength(); j++) {
            Node childNode = childList.item(j);
            if ("TaskID".equals(childNode.getNodeName())) {
                System.out.println(childList.item(j).getTextContent()
                        .trim());
            }
        }
    }
}

You'd need to use a FileReader instead if your input came from a file.

Document document = builder.parse(new InputSource(new FileReader(
        new File("foo.xml"))));

An alternative to getElementsByTagName() is XPath, a query language for XML, this is particularly useful if you have complicated set of conditions to match.

XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//flow/TaskID/text()");

Object result = expr.evaluate(document, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
    System.out.println(nodes.item(i).getTextContent());
}

If your XML file is large, like 100s of MB / GB or you're on a low memory platform then consider a SAX parser.

String input = "<flow><TaskID>100</TaskID><TaskID>101</TaskID><TaskID>102</TaskID><TaskID>103</TaskID></flow>";
SAXParser sax = SAXParserFactory.newInstance().newSAXParser();
DefaultHandler handler = new DefaultHandler() {
    private StringBuilder buffer = new StringBuilder();
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if ("TaskID".equals(qName)) {
            System.out.println(buffer);
            buffer = new StringBuilder();
        }
    }
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        buffer.append(ch, start, length);
    }
    @Override
    public void startElement(String uri, String localName,
            String qName, Attributes attributes) throws SAXException {
        buffer = new StringBuilder();
    }
};
sax.parse(new InputSource(new StringReader(input)), handler);
like image 70
Adam Avatar answered Oct 29 '25 00:10

Adam


Here's an example using JDOM, which provides a more pleasant API over existing Java XML parsers:

import java.io.File;
import org.jdom2.*;
import org.jdom2.input.*;

public class Test {
    // TODO: More appropriate exception handling :)
    public static void main (String[] args) throws Exception {
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(new File("test.xml"));
        Element root = doc.getRootElement();
        for (Element element : root.getChildren("TaskID")) {
            System.out.println(element.getText());
        }
    }
}

Of course, this assumes that the XML document is small enough to be loaded into memory.

(Obviously you can use the built-in libraries too, and if you're not doing much XML work then that would be fine - I just find them a bit primitive if you're doing any significant amount of work.)

like image 37
Jon Skeet Avatar answered Oct 29 '25 00:10

Jon Skeet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!