A.J
A.J

Reputation: 1180

Getting child node Java

I have the following code

        try {
            String xml = "<ADDITIONALIDENT><FEATURE MID=\"TEST\"><NAME>ONE NAME</NAME><VALUE>ONE VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>TWO NAME</NAME><VALUE>TWO VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>THREE NAME</NAME><VALUE>THREE VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>FOUR NAME</NAME><VALUE>FOUR VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>FIVE NAME</NAME><VALUE>FIVE VALUE</VALUE></FEATURE></ADDITIONALIDENT>";

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            dbFactory.setNamespaceAware(true);
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document document = dBuilder.newDocument();
            document = dBuilder.parse(new InputSource(new StringReader(xml)));

            NodeList featureList = document.getElementsByTagName("FEATURE");
            for (int i = 0; i < featureList.getLength(); i++) {
                Element featureElement = (Element) featureList.item(i);
                NodeList nameList = featureElement.getElementsByTagName("NAME");
                NodeList valueList = featureElement.getElementsByTagName("VALUE");
                System.out.println("THIS IS NAME: " + nameList.item(0).getTextContent());
                System.out.println("THIS IS VALUE: " + valueList.item(0).getTextContent());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

It works fine and it finds the correct values, but I don't think I am doing it the right way. I feel like I shouldn't be using lists within the actual featureList Element.

Is there a way to get the values without making two lists?

<ADDITIONALIDENT>
    <FEATURE MID="TEST">
        <NAME>ONE NAME</NAME>
        <VALUE>ONE VALUE</VALUE>
    </FEATURE>
    <FEATURE MID="TEST">
        <NAME>TWO NAME</NAME>
        <VALUE>TWO VALUE</VALUE>
    </FEATURE>
<ADDITIONALIDENT>

Upvotes: 1

Views: 783

Answers (2)

Lakshan
Lakshan

Reputation: 1436

try with following solution,

try {
    String xml = "YOUR_XML_CONTEN";

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    dbFactory.setNamespaceAware(true);
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document document = dBuilder.newDocument();
    document = dBuilder.parse(new InputSource(new StringReader(xml)));

    NodeList featureList = document.getElementsByTagName("FEATURE");
        for (int i = 0; i < featureList.getLength(); i++) {
            Element featureElement = (Element) featureList.item(i);
            System.out.println("THIS IS NAME: " + 
            featureElement.getElementsByTagName("NAME").item(0).getTextContent());
            System.out.println("THIS IS VALUE: " + 
            featureElement.getElementsByTagName("VALUE").item(0).getTextContent());
        }
    } catch (Exception e) {
       e.printStackTrace();
}

output,

THIS IS NAME: ONE NAME
THIS IS VALUE: ONE VALUE
THIS IS NAME: TWO NAME
THIS IS VALUE: TWO VALUE
THIS IS NAME: THREE NAME
THIS IS VALUE: THREE VALUE
THIS IS NAME: FOUR NAME
THIS IS VALUE: FOUR VALUE
THIS IS NAME: FIVE NAME
THIS IS VALUE: FIVE VALUE

Upvotes: 2

kimbert
kimbert

Reputation: 2422

Good question. There are several ways to query an XML document using Java:

a) Parse the XML document into a Document and use getElementsByTagName to extract the nodes that you need. This is your current approach. It is OK for simple documents but it does not scale well because the Document class knows nothing about the structure of the document. The getElementsByTagName() method has to assume that any tag that it finds might occur more than once. But you can fix that...

b) Generate Java classes for your specific document structure. This requires you to have an XML schema that describes the structure of your XML. You can then use JAXB to generate Java classes to process your specific XML format. In your example, the generated code would know (from the schema) that there is exactly one instance of NAME and VALUE within each FEATURE tag. The getter methods for NAME and VALUE would return a single Node, so your code would not need to use arrays for single-occurrence elements. See https://docs.oracle.com/javase/tutorial/jaxb/intro/index.html for more details.

c) Use the XPath support that is built into Java to extract exactly the nodes that you need. XPath is designed for processing XML documents and is very powerful and flexible. See How to read XML using XPath in Java for more details.

Option a) is hardly ever used for processing non-trivial XML documents. Both b) and c) are very common.

Upvotes: 1

Related Questions