Rajyalakshmi S
Rajyalakshmi S

Reputation: 173

Java xml Parsing For Two Tags with Same Name

I am writing a code to parse xml file. I want to retrieve the country tag values from this and save that to String[]. When I am trying to do, its retrieving only one value. But I have country tag repeated twice in xml. In future it can be thrice or 4 times and so on which is dynamic. This is my xml:

<?xml version="1.0"?>
<metadata>
<Country>All Countries</Country>
<Country>US - United States</Country>
</metadata>

This is my code:

private static String parseXml(String xmlData)
        throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilder builder = DocumentBuilderFactory.newInstance()
            .newDocumentBuilder();
    InputSource src = new InputSource();
    src.setCharacterStream(new StringReader(xmlData));
    Document doc = builder.parse(src);
    NodeList nodes = doc.getElementsByTagName("metadata");
    Element line = null;
    String cnt = null;
    for (int i = 0; i < nodes.getLength(); i++) {
        Element element = (Element) nodes.item(i);
        NodeList country = element.getElementsByTagName("Country");
        for (int j = 0; j < country.getLength(); j++) {
            if (country != null) {
                System.out.println("Country not null " + country);
                line = (Element) country.item(0);
                if (line != null) {
                    cnt = getCharacterDataFromElement(line);
                }
            }
        }
    }
    return cnt;

}

public static String getCharacterDataFromElement(Element e) {
    Node child = e.getFirstChild();
    if (child instanceof CharacterData) {
        CharacterData cd = (CharacterData) child;
        if (cd != null) {
            return cd.getData();
        }
    }
    return "";
}

Upvotes: 3

Views: 7778

Answers (4)

Santhosh Kumar Tekuri
Santhosh Kumar Tekuri

Reputation: 3020

private static String[] getCountries(String xmlData) throws Exception{
    List<String> result = new ArrayList<String>();
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    InputSource src = new InputSource(new StringReader(xmlData));
    Document doc = builder.parse(src);
    NodeList nodes = doc.getElementsByTagName("metadata");
    for(int i = 0; i < nodes.getLength(); i++){
        Element metadata = (Element)nodes.item(i);
        NodeList countries = metadata.getElementsByTagName("Country");
        for(int j = 0; j < countries.getLength(); j++){
            result.add(countries.item(j).getTextContent());
        }
    }
    return result.toArray(new String[result.size()]);
}

Upvotes: 1

Titus
Titus

Reputation: 22474

Try this:

public class Test {

    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
        System.out
            .println(Arrays
                    .toString(parseXml("<?xml version=\"1.0\"?><metadata><Country>All Countries</Country><Country>US - United States</Country></metadata>")));
    }

    private static String[] parseXml(String xmlData) throws SAXException, IOException, ParserConfigurationException {
        ArrayList<String> list = new ArrayList<String>();
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        InputSource src = new InputSource();
        src.setCharacterStream(new StringReader(xmlData));
        Document doc = builder.parse(src);
        NodeList nodes = doc.getElementsByTagName("metadata");
        for (int i = 0; i < nodes.getLength(); i++) {
            Element element = (Element) nodes.item(i);
            NodeList country = element.getElementsByTagName("Country");
            for (int j = 0; j < country.getLength(); j++) {
                list.add(country.item(j).getTextContent());
            }
        }
        return list.toArray(new String[list.size()]);
    }
}

Upvotes: 1

TheCodingFrog
TheCodingFrog

Reputation: 3504

You need to make two modifications in your program

  1. item(0) should be replaced with item(j)

  2. You can get the value of country using line.getFirstChild().getNodeValue()

Below is updated class XmlParser.java

import java.io.IOException;
import java.io.StringReader;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XmlParser {


    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        String xml = "<?xml version=\"1.0\"?> "
                + "<metadata> "
                + "<Country>All Countries</Country> "
                + "<Country>US - United States</Country> "
                + "</metadata>";
        parseXml(xml);
    }

    private static String parseXml(String xmlData)
            throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder();
        InputSource src = new InputSource();
        src.setCharacterStream(new StringReader(xmlData));
        Document doc = builder.parse(src);
        NodeList nodes = doc.getElementsByTagName("metadata");
        Element line = null;
        String cnt = null;
        for (int i = 0; i < nodes.getLength(); i++) {
            Element element = (Element) nodes.item(i);
            NodeList country = element.getElementsByTagName("Country");
            for (int j = 0; j < country.getLength(); j++) {
                if (country != null) {
                    System.out.println("Country not null " + country);
                    line = (Element) country.item(j);
                    System.out.println("value :: " + line.getFirstChild().getNodeValue());
                }
            }
        }
        return cnt;

    }

    public static String getCharacterDataFromElement(Element e) {
        Node child = e.getFirstChild();
        if (child instanceof org.w3c.dom.CharacterData) {
            org.w3c.dom.CharacterData cd = (org.w3c.dom.CharacterData) child;
            if (cd != null) {
                return cd.getData();
            }
        }
        return "";
    }
}

And output below:

Country not null com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl@51f45f2a value :: All Countries

Country not null com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl@51f45f2a value :: US - United States

Upvotes: 1

Jo Oko
Jo Oko

Reputation: 358

Your code does not provide any possibility to store a list of countries in your code, although it iterates over all countries.

The following should help (although untested): Change String cnt = null; to List<String> = new ArrayList<String>() and do instead of

for (int j = 0; j < country.getLength(); j++) {
    if (country != null) {
        System.out.println("Country not null " + country);
        line = (Element) country.item(0);
        if (line != null) {
            cnt = getCharacterDataFromElement(line);
        }
    }
}

the following:

if (country != null) {
    System.out.println("Country not null " + country);
    for (int j = 0; j < country.getLength(); j++) {
        line = (Element) country.item(j);
        if (line != null) {
            cnt.add( getCharacterDataFromElement(line));
        }
    }
}

Upvotes: 2

Related Questions