Reputation: 875
I need to parse an xml file called students, every student has rollno, firstname, lastname as attributes, but not all student has a club. The xml file looks like this:
<?xml version="1.0"?>
<class>
<student rollno="393" firstname="Dinkar" lastname="Kad">
<club name="Asian-Caucus" />
</student>
<student rollno="493" firstname="Vaneet" lastname="Gupta"/>
<student rollno="593" firstname="jasvir" lastname="jazz">
<club name="Students-for-Corporate-Citizenship"/>
</student>
<student rollno="693" firstname="Joseph" lastname="Patterson"/>
</class>
I would like to retrieve information about each student, get their rollno, first name, lastname and club name if exist. My code can get information about required attributes, but club name is always empty(even when there should be a club associated with this student): My code is like following:
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class TestParser {
public void parseXML() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
File file = new File("c:\\My Documents\\students.xml");
Document doc = docBuilder.parse(file);
NodeList list = doc.getElementsByTagName("student");
for(int i=0; i<list.getLength(); i++){
int rollno = 0;
String firstname = "";
String lastname = "";
String clubname = "";
Element cur = (Element)list.item(i);
NamedNodeMap curAttr = cur.getAttributes();
for(int j=0; j<curAttr.getLength(); j++){
Node attr = curAttr.item(j);
if(attr.getNodeName().equals("rollno"))
rollno = Integer.parseInt(attr.getNodeValue());
if(attr.getNodeName().equals("firstname"))
firstname = attr.getNodeValue();
if(attr.getNodeName().equals("lastname"))
lastname = attr.getNodeValue();
if(attr.getNodeName().equals("club name"))
clubname = attr.getNodeValue();
} // end for each attribute
System.out.print("rollno: " + rollno);
System.out.print(" firstname: " + firstname);
System.out.print(" lastname: " + lastname);
System.out.println(" club name: " + clubname);
}// end for each element
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
TestParser tp = new TestParser();
tp.parseXML();
}
}
Output looks like this:
rollno: 393 firstname: Dinkar lastname: Kad club name:
rollno: 493 firstname: Vaneet lastname: Gupta club name:
rollno: 593 firstname: jasvir lastname: jazz club name:
rollno: 693 firstname: Joseph lastname: Patterson club name:
Any idea to fix this problem, so that student has a club can print out the correct club name? I'm very new to xml parsing, any suggestion is appreciated. Thanks a lot!
Update: Revised the code according to answer by @tanjir, now the program can get childnode club's value smoothly:)
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class TestParser {
public void parseXML() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
File file = new File("c:\\My Documents\\students.xml");
Document doc = docBuilder.parse(file);
NodeList list = doc.getElementsByTagName("student");
for(int i=0; i<list.getLength(); i++){
int rollno = 0;
String firstname = "";
String lastname = "";
String clubname = "";
Element cur = (Element)list.item(i);
NamedNodeMap curAttr = cur.getAttributes();
for(int j=0; j<curAttr.getLength(); j++){
Node attr = curAttr.item(j);
if(attr.getNodeName().equals("rollno"))
rollno = Integer.parseInt(attr.getNodeValue());
if(attr.getNodeName().equals("firstname"))
firstname = attr.getNodeValue();
if(attr.getNodeName().equals("lastname"))
lastname = attr.getNodeValue();
if(attr.getNodeName().equals("name"))
clubname = attr.getNodeValue();
} // end for each attribute
//check if there is any optional childnode
if(cur.hasChildNodes()) {
NodeList stChildNodes = cur.getChildNodes();
// Loop through all the nodes and find the club node only
for(int c=0; c<stChildNodes.getLength(); c++) {
Node child = stChildNodes.item(c);
if(child.getNodeName().equals("club")) {
//"club" node detected. now loop through the attributes
NamedNodeMap curChildAttr = child.getAttributes();
for(int j=0; j<curChildAttr.getLength(); j++){
Node attr = curChildAttr.item(j);
if(attr.getNodeName().equals("name")) {
clubname = attr.getNodeValue();
}
}
}
}
}// end if hasChildNodes
System.out.print("rollno: " + rollno);
System.out.print(" firstname: " + firstname);
System.out.print(" lastname: " + lastname);
System.out.println(" club name: " + clubname);
}// end for each element
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
TestParser tp = new TestParser();
tp.parseXML();
}
}
Upvotes: 1
Views: 1169
Reputation: 1334
You need to get the club node and then loop through it's attribute- similar to the way you already did..
//check if there is any optional childnode
if(cur.hasChildNodes()) {
NodeList stChildNodes = cur.getChildNodes();
// Loop through all the nodes and find the club node only
for(Node child : stChildNodes) {
if(child.getNodeName().equals("club") {
//"club" node detected. now loop through the attributes like the way you already did for students
NamedNodeMap clubAttr = child.getAttributes();
for(int j=0; j<clubAttr.getLength(); j++){
Node clattr = clubAttr.item(j);
if(clattr.getNodeName().equals("name")) {
clubname = clattr.getNodeValue();
}
}
break; // probably we are not interested in other nodes
}
}
}
Upvotes: 2