Saturday, 15 June 2013

SAX (Simple API for XML) Parser in Java

In my last post, I discussed about DOM parser. In this post, I am going to discuss about SAX parser which I found far more better and simple than DOM parser. As I said before - Simple API for XML (SAX), an event-driven, serial-access mechanism for accessing XML documents. This protocol is frequently used by servlets and network-oriented programs that need to transmit and receive XML documents, because it is the fastest and least memory-intensive mechanism that is currently available for dealing with XML documents.

The most important interface is ContentHandler. This interface requires a number of methods that the SAX parser invokes in response to various parsing events. The major event-handling methods are:

1.  startDocument
2.  endDocument 
3.  startElement
4.  endElement

The easiest way to implement this interface is to extend the DefaultHandler class, defined in the org.xml.sax.helpers package. That class provides do-nothing methods for all the ContentHandler events.

Since it’s an event based parsing it contains default handler for handling the events whenever SAX parser parses the xml document and it finds the Start tag and end tag, it calls corresponding handler method.
Lets take an example to understand the implementation of SAX parser:

XML

<?xml version="1.0"?>
<company name="Google">
	<employee id="1001">
		<name>Ankit Pandoh</name>
		<salary>100000</salary>
		<address>Bangalore</address>
		<contact>99999</contact>
	</employee>
	<employee id="1002">
		<name>Sumit Malhotra</name>
		<salary>200000</salary>
		<address>Delhi</address>
		<contact>95338</contact>
	</employee>
</company>

Class SAXParserImplementation




package parser;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

public class SAXParserImplementation extends DefaultHandler
{
	private String xmlFile;
	private Employee employee;
	private String text;
	List<Employee> employees = new ArrayList<Employee>();

	public static void main(String args[])
	{
		String xmlFile = args[0];
		SAXParserImplementation parser = new SAXParserImplementation(xmlFile);
		parser.displayEmployee();
	}

	SAXParserImplementation(String xml)
	{
		this.xmlFile = xml;
		try
		{
			// tell the parser to parse the input file and notify the handler.
			this.getParser().parse(xmlFile, this);
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	private SAXParser getParser()
	{
		// Get Parser Factory to create a SAXParser
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = null;
		try
		{
			// Get parser instance using factory
			parser = factory.newSAXParser();
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		return parser;
	}

	/**
	 * Whenever the parser encounters the beginning of new element, it will call
	 * this method and empty the text buffer.
	 */
	public void startElement(String uri, String localName, String qName,
			Attributes attributes)
	{
		text = "";
		if ("company".equalsIgnoreCase(qName))
		{
			String company = attributes.getValue("name");
			System.out.println("Company Name : " + company);
		}
		if ("employee".equalsIgnoreCase(qName))
		{
			employee = new Employee();
			employee.setId(attributes.getValue("id"));
		}
	}

	/**
	 * This method will be called at the end of each element.
	 */
	public void endElement(String uri, String localName, String qName)
	{
		if ("employee".equalsIgnoreCase(qName))
		{
			employees.add(employee);
		}
		if ("name".equalsIgnoreCase(qName))
		{
			employee.setName(text);
		} else if ("salary".equalsIgnoreCase(qName))
		{
			employee.setSalary(Integer.parseInt(text));
		} else if ("address".equalsIgnoreCase(qName))
		{
			employee.setAddress(text);
		} else if ("contact".equalsIgnoreCase(qName))
		{
			employee.setContact(Integer.parseInt(text));
		}
	}

	/**
	 * When the parser encounters plain text (not XML elements), it calls(this
	 * method, which accumulates them in a string buffer
	 */
	public void characters(char[] buffer, int start, int length)
	{
		text = new String(buffer, start, length);
	}

	private void displayEmployee()
	{
		int i = 1;
		for (Employee employee : employees)
		{
			System.out.println("Details of Employee " + i + ":");
			System.out.println("ID :" + employee.getId());
			System.out.println("Name :" + employee.getName());
			System.out.println("Salary :" + employee.getSalary());
			System.out.println("Address :" + employee.getAddress());
			System.out.println("Contact :" + employee.getContact());
			i++;
			System.out.println();
		}
	}

	// Inner class Employee
	class Employee
	{
		private String id;
		private String name;
		private int salary;
		private String address;
		private int contact;

		public String getId()
		{
			return id;
		}

		public void setId(String id)
		{
			this.id = id;
		}

		public String getName()
		{
			return name;
		}

		public void setName(String name)
		{
			this.name = name;
		}

		public int getSalary()
		{
			return salary;
		}

		public void setSalary(int salary)
		{
			this.salary = salary;
		}

		public String getAddress()
		{
			return address;
		}

		public void setAddress(String address)
		{
			this.address = address;
		}

		public int getContact()
		{
			return contact;
		}

		public void setContact(int contact)
		{
			this.contact = contact;
		}
	}
}

Output

Company Name : Google
Details of Employee 1:
ID :1001
Name :Ankit Pandoh
Salary :100000
Address :Bangalore
Contact :99999

Details of Employee 2:
ID :1002
Name :Sumit Malhotra
Salary :200000
Address :Delhi
Contact :95338

No comments:

Post a Comment