AndroidDev21921 AndroidDev21921 - 3 days ago 5
Java Question

parsing Xml with NodeList and DocumentBuilder and getting values

I've followed almost all of the SO questions and answers, some make sense while others don't, i'm able to get some of my xml working some of the time. At this point I have a hobbled gob of nothing.

Below is my xml that i am trying work with

<GET_GUESS_CHART>
<sort_by_letter>
<letter_row>
<letter>A</letter>
<guess>16</guess>
<rank>3</rank>
</letter_row>
<letter_row>
<letter>B</letter>
<guess>5</guess>
<rank>1</rank>
</letter_row>
</sort_by_letter>
<sort_by_rank>
<letter_row>
<letter>A</letter>
<guess>16</guess>
<rank>1</rank>
</letter_row>
<letter_row>
<letter>E</letter>
<guess>15</guess>
<rank>2</rank>
</letter_row>
</sort_by_rank>
</GET_GUESS_CHART>


I want to loop through the document and loop through 'sort_by_letters' and 'sort_by_rank' and get values for each 'letter_row'.

Here is how i get the document:

URL url = new URL(Url[0]);
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// Download the XML file
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();


I'm able to actually get the document, but for the life of me can not figure how to work it to get what i need.

Answer

All you need to do is to walk the DOM tree...

import java.io.ByteArrayInputStream;

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

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

public class ReadXML {

    private static final String XML = "<?xml version=\"1.0\"?>\n" + "<GET_GUESS_CHART>" + "    <sort_by_letter>" + "        <letter_row>"
            + "            <letter>A</letter>" + "            <guess>16</guess>" + "            <rank>3</rank>" + "        </letter_row>"
            + "        <letter_row>" + "            <letter>B</letter>" + "            <guess>5</guess>" + "            <rank>1</rank>"
            + "        </letter_row>" + "    </sort_by_letter>" + "    <sort_by_rank>" + "        <letter_row>" + "            <letter>A</letter>"
            + "            <guess>16</guess>" + "            <rank>1</rank>" + "        </letter_row>" + "        <letter_row>"
            + "            <letter>E</letter>" + "            <guess>15</guess>" + "            <rank>2</rank>" + "        </letter_row>"
            + "    </sort_by_rank>" + "</GET_GUESS_CHART>";

    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(new ByteArrayInputStream(XML.getBytes()));

        NodeList rootElement = doc.getChildNodes();

        NodeList sortByNodes = rootElement.item(0).getChildNodes();

        for (int k = 0; k < sortByNodes.getLength(); k++) {
            Node sortBy = sortByNodes.item(k);

            System.out.println("SORT BY: " + sortBy.getNodeName());

            NodeList letterRows = sortBy.getChildNodes();

            for (int j = 0; j < letterRows.getLength(); j++) {
                Node letterRow = letterRows.item(j);
                NodeList letterRowDetails = letterRow.getChildNodes();

                if (letterRowDetails.getLength() > 0) {
                    String letter = null;
                    String guess = null;
                    String rank = null;

                    for (int i = 0; i < letterRowDetails.getLength(); i++) {
                        Node detail = letterRowDetails.item(i);

                        if (detail.getNodeName().equals("letter")) {
                            letter = detail.getTextContent();
                        } else if (detail.getNodeName().equals("guess")) {
                            guess = detail.getTextContent();
                        } else if (detail.getNodeName().equals("rank")) {
                            rank = detail.getTextContent();
                        }
                    }

                    System.out.println("Letter=" + letter + ", guess=" + guess + ", rank=" + rank);
                }
            }
        }
    }
}

(You'll probably build an object and add it to some result list instead of the System.out line...)

OUTPUT:

SORT BY: #text
SORT BY: sort_by_letter
Letter=A, guess=16, rank=3
Letter=B, guess=5, rank=1
SORT BY: #text
SORT BY: sort_by_rank
Letter=A, guess=16, rank=1
Letter=E, guess=15, rank=2

To answer the comment: if you wanted to JUST get the "sort_by_letter" XML elements, you can add an extra if clause here...

    ...
    for (int k = 0; k < sortByNodes.getLength(); k++) {
        Node sortBy = sortByNodes.item(k);

        if(sortBy.getNodeName().equals("sort_by_letter")) {
            System.out.println("SORT BY: " + sortBy.getNodeName());
            ...
Comments