Reputation: 173
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
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
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
Reputation: 3504
You need to make two modifications in your program
item(0)
should be replaced with item(j)
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
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