I need to parse document using SAX parser in java. I was able to print all the node values if I use DefaultHandler class traditionally implementing the startElement, endElement and characters method. How can we access the node outside the for loop My Sample XML is:
<Employees>
<Employee id="1">
<age>29</age>
<name>Pankaj</name>
<gender>Male</gender>
<role>Java Developer</role>
</Employee>
<Employee id="2">
<age>35</age>
<name>Lisa</name>
<gender>Female</gender>
<role>CEO</role>
</Employee>
here is my java code with for loop for each employee
public class XMLParserSAX {
public static void main(String[] args) {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = saxParserFactory.newSAXParser();
MyHandler handler = new MyHandler();
saxParser.parse(new File("/Users/yashvanth/IdeaProjects/parsing/src/staff.xml"), handler);
//Get Employees list
List<Employee> empList = handler.getEmpList();
//print employee information
for(Employee emp : empList)
System.out.println(emp);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
}
and my handler class
public class MyHandler extends DefaultHandler {
// List to hold Employees object
private List<Employee> empList = null;
private Employee emp = null;
private StringBuilder data = null;
// getter method for employee list
public List<Employee> getEmpList() {
return empList;
}
boolean bAge = false;
boolean bName = false;
boolean bGender = false;
boolean bRole = false;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("Employee")) {
// create a new Employee and put it in Map
String id = attributes.getValue("id");
// initialize Employee object and set id attribute
emp = new Employee();
emp.setId(Integer.parseInt(id));
// initialize list
if (empList == null)
empList = new ArrayList<>();
} else if (qName.equalsIgnoreCase("name")) {
// set boolean values for fields, will be used in setting Employee variables
bName = true;
} else if (qName.equalsIgnoreCase("age")) {
bAge = true;
} else if (qName.equalsIgnoreCase("gender")) {
bGender = true;
} else if (qName.equalsIgnoreCase("role")) {
bRole = true;
}
// create the data container
data = new StringBuilder();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (bAge) {
// age element, set Employee age
emp.setAge(Integer.parseInt(data.toString()));
bAge = false;
} else if (bName) {
emp.setName(data.toString());
bName = false;
} else if (bRole) {
emp.setRole(data.toString());
bRole = false;
} else if (bGender) {
emp.setGender(data.toString());
bGender = false;
}
if (qName.equalsIgnoreCase("Employee")) {
// add Employee object to list
empList.add(emp);
}
}
@Override
public void characters(char ch[], int start, int length) throws SAXException {
data.append(new String(ch, start, length));
}
}
I'm getting my output as
Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java Developer
Employee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEO
how to read the attribute and add to the output like below
Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java Developer
Employee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEO
At least, you can implement it in the similar way as handler.getEmpList()
:
public static void main(String[] args) {
...
String location = handler.getLocation();
System.out.println("Location: " + location);
// print employees
}
Handler:
public class MyHandler extends DefaultHandler {
....
private boolean locationTagOpen = false;
private String location = null;
public String getLocation() {
return location;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
...
else if (qName.equalsIgnoreCase("location")) {
locationTagOpen = true;
}
...
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (locationTagOpen) {
location = data.toString();
locationTagOpen = false;
}
...
}
}