Saturday, May 9, 2015

XML Reading With SAX Parser

On previous post we learn how to reading a XML file using DOM parser.Here we learn how parse a XML file using SAX(Simple API for XML) parser.

SAX parser is push based eventdriven parser means when we read a XML file then event fire for every tag on XML file and push based means when we try to parse a xml file from application then application cannot have control on this parser it will parse all node and push data to application.

In DOM parser we need to load whole XML file into the memory to read this but in SAX we don't need to load whole XML file into the memory, So we will never get memory out of bound exception for very large XML file.

Using SAX Parser we cannot write a XML file.

We need to follow this steps to parse a XML file

Step 1:
   Create SAXParserFactory instance using
                 SAXParserFactory saxDoc = SAXParserFactory.newInstance();
Step 2:
   Create a SAXParser from SAXParserFactory instance
                 SAXParser saxParser = saxDoc.newSAXParser();
Step 3:
   Create handler for parsing a XML where we define what parser do, when find a StartElement(means <Element>),EndElement(means </Elelement>) or a Character between Start and End Element; for an example:
  
  DefaultHandler handler = new DefaultHandler() {
            @Override
            public void startElement(String uri, String localName,String qName, Attributes attributes)
                    throws SAXException {
                System.out.println("Start Element :" + qName);
            }

            @Override
            public void endElement(String uri, String localName,String qName) throws SAXException {
                System.out.println("End Element :" + qName);
            }

            @Override
            public void characters(char ch[], int start, int length) throws SAXException {

                   System.out.println(new String(ch, start, length));
            }
        }; 


Staep 4:
      Now we need to register this handler to parser using this
              saxParser.parse(new File("FilePath"), handler); 
 

Note :
1. If we are try to use SAXParser 2.0 then we use only
       XMLReader saxParser = XMLReaderFactory.createXMLReader();
 to create parser instance. We don't need to go Step1 for creating factory because it call this internally.
2. For SAXParser 2.0 we need to register handler using
        saxParser.setContentHandler(handler);
and then pass the filename using this
        saxParser.parse(new InputSource("c:/test.xml"));
and ignore the Step 4 code.


package SAXParser;

import java.io.File;
import java.io.IOException;
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 SAXParserExample {

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, VerifyError {
        /**
         * We can pass the class name of the XML parser
         * to the SAXParserFactory.newInstance().
         */

      
        //SAXParserFactory saxDoc = SAXParserFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", null);
      
        SAXParserFactory saxDoc = SAXParserFactory.newInstance();
        SAXParser saxParser = saxDoc.newSAXParser();
        /**
         * If we use SAX 2.0 then we need this line and
         * SAXParserFactory,SAXParser not needed and we
         * can commented out above two lines.
         */

      
        //XMLReader saxParser = XMLReaderFactory.createXMLReader();

        DefaultHandler handler = new DefaultHandler() {
             boolean fname = false;
             boolean lname = false;
             boolean section = false;
        
            @Override
            public void startElement(String uri, String localName, String qName, 

                                                                       Attributes attributes)  throws SAXException {
                System.out.println("Start Element Element :" + qName);
                if (qName.equalsIgnoreCase("FNAME")) {
                 fname = true;
                 }

                 if (qName.equalsIgnoreCase("LNAME")) {
                 lname = true;
                 }

                 if (qName.equalsIgnoreCase("SECTIONNAME")) {
                 section = true;
                 }    

                for (int i=0; i<attributes.getLength(); i++) {
                      String aname = attributes.getLocalName(i);
                      String value = attributes.getValue(i);
                      System.out.println("Attribute Name : " + aname + " Attribut Value : " + value);       
                 }

            @Override
            public void endElement(String uri, String localName, String qName)

                                                              throws SAXException   
            {
                System.out.println("End Element :" + qName);
            }
          
            @Override
            public void characters(char ch[], int start, int length) throws SAXException {
              
                 if (fname) {
                 System.out.println("First Name : " + new String(ch, start, length));
                 fname = false;
                 }

                 if (lname) {
                 System.out.println("Last Name : " + new String(ch, start, length));
                 lname = false;
                 }
                 if (section) {
                 System.out.println("Section Name : " + new String(ch, start, length));
                 section = false;
                 }        
            }
        };
        /**
         * Below two line used if we use SAX 2.0
         * Then last line not needed.
         */

        //saxParser.setContentHandler(handler);
        //saxParser.parse(new InputSource("c:/file.xml"));

        saxParser.parse(new File("c:/file.xml"), handler);
    }
}


 Sample XML :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<student id="1">
  <fname>TestFirstName</fname>
  <lname>TestLastName</lname>
  <sectionname rollno="1">A</sectionname>
</student>
 




 

No comments:

Post a Comment