Friday, December 30, 2011

Step By Step guide to Read XML file in Java Using SAX Parser Example

Reading XML file in java using SAX Parser is little different than reading xml file in Java with DOM parser which we had discussed in last article of this series. This tutorial is can be useful for those who are new to the java world and got the requirement for read an xml file in java in their project or assignment, key feature of java is it provides built in class and object to handle everything which makes our task very easy. Basically this process of handling XML file is known as parsing means break down the whole string into small pieces using the special tokens.
Parsing can be done using two ways:

  • Using DOM Parser
  • Using SAX Parser

Read XML file in Java Using SAX Parser Example

In DOM parser we have seen that we have to follow simple three steps:
Ø      Parse the XML file
Ø      Create the java object
Ø      Manipulate the object means we can read that object or add them to list or whatever function we want we can do
But in SAX Parser its little bit different.

how to parse read xml file sax parser java exampleSAX Parser: it’s an event based parsing it contains default handler for handling the events whenever SAX parser pareses the xml document and it finds the Start tag “<” and end tag”>” it calls corresponding handler method.

Though there are other ways also to get data from xml file e.g. using XPATH in Java which is a language like SQL and give selective data from xml file.

Sample Example of reading XML File – SAX Parser

Suppose we have this sample XML file bank.xml which contains account details of all accounts in a hypothetical bank:

<?xml version="1.0" encoding="UTF-8"?>
<Bank>
      <Account type="saving">
            <Id>1001</Id>
            <Name>Jack Robinson</Name>
            <Amt>10000</Amt>
      </Account>
      <Account type="current">
            <Id>1002</Id>
            <Name>Sony Corporation</Name>
            <Amt>1000000</Amt>
      </Account>
</Bank>



1.      Create the SAX parser and parse the XML file:  In this step we will take one factory instance from SAXParserFactory to parse the xml  file this factory instance in turns  give us instance of parser using the parse() method will parse the Xml file.
2.      Event Handling: when Sax Parser starts the parsing whenever it founds the start or end tag it will invoke the corresponding event handling method which is public void startElement (…) and public void end Element (...).

3.       Register the events: The class extends the Default Handler class to listen for callback events and we register this handler to sax Parser to notify us for call back event

Let see java code for all these steps

To represent data from our sample xml file we need one java domain object called Account:

package parser;

public class Account {

       private String name;
       private int id;
       private int amt;
       private String type;

       public Account() {
       }

       public Account(String name, int id, int amt, String type) {
              this.name = name;
              this.amt = amt;
              this.id = id;
              this.type = type;
       }

       public int getAmt() {
              return amt;
       }

       public void setAmt(int amt) {
              this.amt = amt;
       }

       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 getType() {
              return type;
       }

       public void setType(String type) {
              this.type = type;
       }

       public String toString() {
              StringBuffer sb = new StringBuffer();
              sb.append("Account Details - ");
              sb.append("Name:" + getName());
              sb.append(", ");
              sb.append("Type:" + getType());
              sb.append(", ");
              sb.append("Id:" + getId());
              sb.append(", ");
              sb.append("Age:" + getAmt());
              sb.append(".");

              return sb.toString();
       }
}


Sample Code for implementing SAX parser in Java


package parser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ReadXMLFileUsingSaxparser extends DefaultHandler {

       private Account acct;
       private String temp;
       private ArrayList<Account> accList = new ArrayList<Account>();

       /** The main method sets things up for parsing */
       public static void main(String[] args) throws IOException, SAXException,
                     ParserConfigurationException {
             
              //Create a "parser factory" for creating SAX parsers
              SAXParserFactory spfac = SAXParserFactory.newInstance();

              //Now use the parser factory to create a SAXParser object
              SAXParser sp = spfac.newSAXParser();

              //Create an instance of this class; it defines all the handler methods
              ReadXMLFileUsingSaxparser handler = new ReadXMLFileUsingSaxparser();

              //Finally, tell the parser to parse the input and notify the handler
              sp.parse("bank.xml", handler);
             
              handler.readList();

       }


       /*
        * 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) {
              temp = new String(buffer, start, length);
       }
      

       /*
        * Every time the parser encounters the beginning of a new element,
        * it calls this method, which resets the string buffer
        */ 
       public void startElement(String uri, String localName,
                     String qName, Attributes attributes) throws SAXException {
              temp = "";
              if (qName.equalsIgnoreCase("Account")) {
                     acct = new Account();
                     acct.setType(attributes.getValue("type"));

              }
       }

       /*
        * When the parser encounters the end of an element, it calls this method
        */
       public void endElement(String uri, String localName, String qName)
                     throws SAXException {

              if (qName.equalsIgnoreCase("Account")) {
                     // add it to the list
                     accList.add(acct);

              } else if (qName.equalsIgnoreCase("Name")) {
                     acct.setName(temp);
              } else if (qName.equalsIgnoreCase("Id")) {
                     acct.setId(Integer.parseInt(temp));
              } else if (qName.equalsIgnoreCase("Amt")) {
                     acct.setAmt(Integer.parseInt(temp));
              }

       }

       private void readList() {
              System.out.println("No of  the accounts in bank '" + accList.size()  + "'.");
              Iterator<Account> it = accList.iterator();
              while (it.hasNext()) {
                     System.out.println(it.next().toString());
              }
       }
      
}

Output:
No of  the accounts in bank '2'.
Account Details - Name:Jack Robinson, Type:saving, Id:1001, Age:10000.
Account Details - Name:Sony Corporation, Type:current, Id:1002, Age:1000000.
 



Advantage of SAX parser in Java:
It is faster than DOM parser because it will not load the XML document into the memory .its an event based.

Some other Tutorial you may like



7 comments :

Brooke Maddox said...

Can I use SAX in a servlet and have it save the data objects to a Java Bean?

Anonymous said...

Nice explanation, can u please tell me one thing
if i am not calling , handler.readList();
than all three methods startElemnt() endElemnt() ... are not being called , what is the issue ?

Anonymous said...

@anonymous...As far as i know, the parser calls these methods as it comes accross the various checkpoints i.e startElement(), endElement() etc he explains this in the main parser class :

//Finally, tell the parser to parse the input and notify the handler
sp.parse("bank.xml", handler);


Manish Modi said...

Below code will parse whole file using startElement, characters, endElement methods
when parser reads start tag ex. then startElement() calls automatically, same as endElement() calls when it reads and characters() calls when it reads data1 data1.
Here readList() is our own method so we have to explicitly call it as shown above handler.readList();

Ross Cadogan said...

Your implementation of characters() may not store all of an element's CDATA. SAX may call characters() multiple times between calls to start/endElement() as it refills its internal character buffer. Instead, try appending characters to a StringBuffer which gets cleared on each element encountered:

public void startElement(...) {
this.cdata = new StringBuffer(); // clear the buffer
}
public void characters(char[] ch, int start, int length) {
this.cdata.append(ch, start, length);
}

Ashwini Patro said...

why it showing Error....in line on 4.
SAXParserFactory spf=SAXParserFactory.newInstance();
SAXParser sp=spf.newSAXParser();
ParsingXmlFileUsingSaxparser handler=new ParsingXmlFileUsingSaxparser();
sp.parse("Bank.xml", handler);
handler.readlist();

It shows "The method parse(String, HandlerBase) in the type SAXParser is not applicable for the arguments (String, ParsingXmlFileUsingSaxparser)".

Anonymous said...

How to Insert data in Xml file after a specific tag any help please??

Post a Comment