Java Source Code Parser Example

SAX Parser in java provides API to parse XML documents. SAX parser is different from DOM parser because it doesn't load complete XML into memory and read xml document sequentially.

SAX Parser

sax parser, sax parser example, java sax parser

javax.xml.parsers.SAXParser provides method to parse XML document using event handlers. This class implements XMLReader interface and provides overloaded versions of parse() methods to read XML document from File, InputStream, SAX InputSource and String URI.

The actual parsing is done by the Handler class. We need to create our own handler class to parse the XML document. We need to implement org.xml.sax.ContentHandler interface to create our own handler classes. This interface contains callback methods that receive notification when an event occurs. For example StartDocument, EndDocument, StartElement, EndElement, CharacterData etc.

org.xml.sax.helpers.DefaultHandler provides default implementation of ContentHandler interface and we can extend this class to create our own handler. It's advisable to extend this class because we might need only a few of the methods to implement. Extending this class will keep our code cleaner and maintainable.

SAX parser Example

Let's jump to the SAX parser example program now, I will explain different features in detail later on.

employees.xml

                          <?xml version="1.0" encoding="UTF-8"?> <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> 	<Employee id="3"> 		<age>40</age> 		<name>Tom</name> 		<gender>Male</gender> 		<role>Manager</role> 	</Employee> 	<Employee id="4"> 		<age>25</age> 		<name>Meghna</name> 		<gender>Female</gender> 		<role>Manager</role> 	</Employee> </Employees>                      

So we have a XML file stored somewhere in file system and by looking at it, we can conclude that it contains list of Employee. Every Employee has id attribute and fields age, name, gender and role.

We will use SAX parser to parse this XML and create a list of Employee object.

Here is the Employee object representing Employee element from XML.

                          package com.journaldev.xml;  public class Employee {     private int id;     private String name;     private String gender;     private int age;     private String role;          public int getId() {         return id;     }     public void setId(int id) {         this.id = id;     }     public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     }     public String getGender() {         return gender;     }     public void setGender(String gender) {         this.gender = gender;     }     public int getAge() {         return age;     }     public void setAge(int age) {         this.age = age;     }     public String getRole() {         return role;     }     public void setRole(String role) {         this.role = role;     }          @Override     public String toString() {         return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender +                 " Role=" + this.role;     }      }                      

Let's create our own SAX Parser Handler class extending DefaultHandler class.

                          package com.journaldev.xml.sax;  import java.util.ArrayList; import java.util.List;  import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;  import com.journaldev.xml.Employee;  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)); 	} }                      

MyHandler contains the list of the Employee object as a field with a getter method only. The Employee objects are getting added in the event handler methods. Also, we have an Employee field that will be used to create an Employee object and once all the fields are set, add it to the employee list.

SAX parser methods to override

The important methods to override are startElement(), endElement() and characters().

SAXParser starts parsing the document, when any start element is found, startElement() method is called. We are overriding this method to set boolean variables that will be used to identify the element.

We are also using this method to create a new Employee object every time Employee start element is found. Check how id attribute is read here to set the Employee Object id field.

characters() method is called when character data is found by SAXParser inside an element. Note that SAX parser may divide the data into multiple chunks and call characters() method multiple times (Read ContentHandler class characters() method documentation). That's why we are using StringBuilder to keep this data using append() method.

The endElement() is the place where we use the StringBuilder data to set employee object properties and add Employee object to the list whenever we found Employee end element tag.

Below is the test program that uses MyHandler to parse above XML to list of Employee objects.

                          package com.journaldev.xml.sax;  import java.io.File; import java.io.IOException; import java.util.List;  import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory;  import org.xml.sax.SAXException;  import com.journaldev.xml.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/pankaj/employees.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();     }     }  }                      

Here is the output of the above program.

                          Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java Developer Employee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEO Employee:: ID=3 Name=Tom Age=40 Gender=Male Role=Manager Employee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager                      

SAXParserFactory provides factory methods to get the SAXParser instance. We are passing File object to the parse method along with MyHandler instance to handle the callback events.

SAXParser is a little bit confusing in the start but if you are working on a large XML document, it provides a more efficient way to read XML than DOM Parser. That's all for SAX Parser in Java.

Reference: SAXParser, DefaultHandler

ellefsonbeestre.blogspot.com

Source: https://www.journaldev.com/1198/java-sax-parser-example

0 Response to "Java Source Code Parser Example"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel