if we do this in SAX Parser:
public class SAXXMLHandler extends DefaultHandler {
private List<Employee> employees;
private String tempVal;
private Employee tempEmp;
public SAXXMLHandler() {
employees = new ArrayList<Employee>();
}
public List<Employee> getEmployees() {
return employees;
}
// Event Handlers
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equalsIgnoreCase("employee")) {
// create a new instance of employee
tempEmp = new Employee();
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equalsIgnoreCase("employee")) {
// add it to the list
employees.add(tempEmp);
} else if (qName.equalsIgnoreCase("id")) {
tempEmp.setId(Integer.parseInt(tempVal));
} else if (qName.equalsIgnoreCase("name")) {
tempEmp.setName(tempVal);
} else if (qName.equalsIgnoreCase("department")) {
tempEmp.setDepartment(tempVal);
} else if (qName.equalsIgnoreCase("type")) {
tempEmp.setType(tempVal);
} else if (qName.equalsIgnoreCase("email")) {
tempEmp.setEmail(tempVal);
}
}
}
for this :
<employee>
<id>2163</id>
<name>Kumar</name>
<department>Development</department>
<type>Permanent</type>
<email>kumar@tot.com</email>
</employee>
What we will do in SAX Parser for this :
<MyResource>
<Item>First</Item>
<Item>Second</Item>
</MyResource>
I am a newbie to SAX Parser.
Previously i had problems with DOM and PullParser for the same XML.
Isn't there any parser built for parsing this simple XML.
To parse an entry named MyResource
that contains multiple entry of Item
you can do something like that :
At first, initialize your variables inside the startDocument method to allow the reuse of your Handler :
private List<MyResource> resources;
private MyResource currentResource;
private StringBuilder stringBuilder;
public void startDocument() throws SAXException {
map = null;
employees = new ArrayList<Employee>();
stringBuilder = new StringBuilder();
}
Detect inside of startElement
when a MyResource
is starting. The tag name will usually be stored inside the qName
argument.
When a MyResource is starting, you may want to create an instance of MyResource as a temporary variable. You will feed it until its end tag is reached.
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if ("MyResource".equals(qName)) {
currentResource = new MyResource();
}
stringBuilder.setLength(0); // Reset the string builder
}
The characters
method is required to read the content of each tag.
Use StringBuilder to read characters. SAX may call more than once the characters method for each tag :
public void characters(char[] ch, int start, int length) throws SAXException {
stringBuilder.append(ch, start, length);
}
Inside the endElement
, create a new Item
each time the closed tag is named item
AND a MyResource is being created (i.e. you have an instance of MyResource somewhere).
When the closed tag is MyResource
, add it to a list of results and clean the temporary variable.
public void endElement(String uri, String localName, String qName) throws SAXException {
if("MyResource".equals(qName)) {
resources.add(currentResource);
currentResource = null;
} else if(currentResource != null && "Item".equals(qName)) {
currentResource.addItem(new Item(stringBuilder.toString()));
}
}
I am assuming that you have a List
of Item
inside MyResource
.
Don't forget to add a method to retrieve the resources after the parse :
List<MyResources> getResources() {
return resources;
}