I happen to read through a chapter on XML parsing and building APIs in Java. And I tried out the different parser available on a sample XML. Then I thought of sharing it on my blog so that I can have a reference to the code as well as a reference for anyone reading this. In this post I parse the same XML in different parsers to perform the same operation of populating the XML content into objects and then adding the objects to a list.
The sample XML considered in the examples is:
03 | < firstName >Rakesh</ firstName > |
04 | < lastName >Mishra</ lastName > |
05 | < location >Bangalore</ location > |
08 | < firstName >John</ firstName > |
09 | < lastName >Davis</ lastName > |
10 | < location >Chennai</ location > |
13 | < firstName >Rajesh</ firstName > |
14 | < lastName >Sharma</ lastName > |
15 | < location >Pune</ location > |
And the obejct into which the XML content is to be extracted is defined as below:
08 | public String toString() { |
09 | return firstName+ " " +lastName+ "(" +id+ ")" +location; |
There are 3 main parsers for which I have given sample code:
Using DOM Parser
I am making use of the DOM parser implementation that comes with the JDK and in my example I am using JDK 7. The DOM Parser loads the complete XML content into a Tree structure. And we iterate through the Node and NodeList to get the content of the XML. The code for XML parsing using DOM parser is given below.
01 | public class DOMParserDemo { |
03 | public static void main(String[] args) throws Exception { |
05 | DocumentBuilderFactory factory = |
06 | DocumentBuilderFactory.newInstance(); |
09 | DocumentBuilder builder = factory.newDocumentBuilder(); |
15 | ClassLoader.getSystemResourceAsStream( "xml/employee.xml" )); |
17 | List<Employee> empList = new ArrayList<>(); |
20 | NodeList nodeList = document.getDocumentElement().getChildNodes(); |
22 | for ( int i = 0 ; i < nodeList.getLength(); i++) { |
25 | Node node = nodeList.item(i); |
26 | if (node instanceof Element) { |
27 | Employee emp = new Employee(); |
28 | emp.id = node.getAttributes(). |
29 | getNamedItem( "id" ).getNodeValue(); |
31 | NodeList childNodes = node.getChildNodes(); |
32 | for ( int j = 0 ; j < childNodes.getLength(); j++) { |
33 | Node cNode = childNodes.item(j); |
36 | if (cNode instanceof Element) { |
37 | String content = cNode.getLastChild(). |
38 | getTextContent().trim(); |
39 | switch (cNode.getNodeName()) { |
41 | emp.firstName = content; |
44 | emp.lastName = content; |
47 | emp.location = content; |
58 | for (Employee emp : empList) { |
59 | System.out.println(emp); |
72 | public String toString() { |
73 | return firstName+ " " +lastName+ "(" +id+ ")" +location; |
The output for the above will be:
1 | Rakesh Mishra(111)Bangalore |
Using SAX Parser
SAX Parser is different from the DOM Parser where SAX parser doesn’t load the complete XML into the memory, instead it parses the XML line by line triggering different events as and when it encounters different elements like: opening tag, closing tag, character data, comments and so on. This is the reason why SAX Parser is called an event based parser.
Along with the XML source file, we also register a handler which extends the DefaultHandler class. The DefaultHandler class provides different callbacks out of which we would be interested in:
- startElement() – triggers this event when the start of the tag is encountered.
- endElement() – triggers this event when the end of the tag is encountered.
- characters() – triggers this event when it encounters some text data.
The code for parsing the XML using SAX Parser is given below:
01 | import java.util.ArrayList; |
02 | import java.util.List; |
03 | import javax.xml.parsers.SAXParser; |
04 | import javax.xml.parsers.SAXParserFactory; |
05 | import org.xml.sax.Attributes; |
06 | import org.xml.sax.SAXException; |
07 | import org.xml.sax.helpers.DefaultHandler; |
09 | public class SAXParserDemo { |
11 | public static void main(String[] args) throws Exception { |
12 | SAXParserFactory parserFactor = SAXParserFactory.newInstance(); |
13 | SAXParser parser = parserFactor.newSAXParser(); |
14 | SAXHandler handler = new SAXHandler(); |
15 | parser.parse(ClassLoader.getSystemResourceAsStream( "xml/employee.xml" ), |
19 | for ( Employee emp : handler.empList){ |
20 | System.out.println(emp); |
25 | * The Handler for SAX Events. |
27 | class SAXHandler extends DefaultHandler { |
29 | List<Employee> empList = new ArrayList<>(); |
31 | String content = null ; |
34 | public void startElement(String uri, String localName, |
35 | String qName, Attributes attributes) |
42 | emp.id = attributes.getValue( "id" ); |
48 | public void endElement(String uri, String localName, |
49 | String qName) throws SAXException { |
57 | emp.firstName = content; |
60 | emp.lastName = content; |
63 | emp.location = content; |
69 | public void characters( char [] ch, int start, int length) |
71 | content = String.copyValueOf(ch, start, length).trim(); |
84 | public String toString() { |
85 | return firstName + " " + lastName + "(" + id + ")" + location; |
The output for the above would be:
1 | Rakesh Mishra(111)Bangalore |
Using StAX Parser
StAX stands for Streaming API for XML and StAX Parser is different from DOM in the same way SAX Parser is. StAX parser is also in a subtle way different from SAX parser.
- The SAX Parser pushes the data but StAX parser pulls the required data from the XML.
- The StAX parser maintains a cursor at the current position in the document allows to extract the content available at the cursor whereas SAX parser issues events as and when certain data is encountered.
XMLInputFactory and XMLStreamReader are the two class which can be used to load an XML file. And as we read through the XML file using XMLStreamReader, events are generated in the form of integer values and these are then compared with the constants inXMLStreamConstants. The below code shows how to parse XML using StAX parser:
01 | import java.util.ArrayList; |
02 | import java.util.List; |
03 | import javax.xml.stream.XMLInputFactory; |
04 | import javax.xml.stream.XMLStreamConstants; |
05 | import javax.xml.stream.XMLStreamException; |
06 | import javax.xml.stream.XMLStreamReader; |
08 | public class StaxParserDemo { |
09 | public static void main(String[] args) throws XMLStreamException { |
10 | List<Employee> empList = null ; |
11 | Employee currEmp = null ; |
12 | String tagContent = null ; |
13 | XMLInputFactory factory = XMLInputFactory.newInstance(); |
14 | XMLStreamReader reader = |
15 | factory.createXMLStreamReader( |
16 | ClassLoader.getSystemResourceAsStream( "xml/employee.xml" )); |
18 | while (reader.hasNext()){ |
19 | int event = reader.next(); |
22 | case XMLStreamConstants.START_ELEMENT: |
23 | if ( "employee" .equals(reader.getLocalName())){ |
24 | currEmp = new Employee(); |
25 | currEmp.id = reader.getAttributeValue( 0 ); |
27 | if ( "employees" .equals(reader.getLocalName())){ |
28 | empList = new ArrayList<>(); |
32 | case XMLStreamConstants.CHARACTERS: |
33 | tagContent = reader.getText().trim(); |
36 | case XMLStreamConstants.END_ELEMENT: |
37 | switch (reader.getLocalName()){ |
42 | currEmp.firstName = tagContent; |
45 | currEmp.lastName = tagContent; |
48 | currEmp.location = tagContent; |
53 | case XMLStreamConstants.START_DOCUMENT: |
54 | empList = new ArrayList<>(); |
61 | for ( Employee emp : empList){ |
62 | System.out.println(emp); |
75 | public String toString(){ |
76 | return firstName+ " " +lastName+ "(" +id+ ") " +location; |
The output for the above is:
1 | Rakesh Mishra(111) Bangalore |
2 | John Davis(112) Chennai |
3 | Rajesh Sharma(113) Pune |
With this I have covered parsing the same XML document and performing the same task of populating the list of Employee
objects using all the three parsers namely: