Sunday, January 5, 2014

XML SAX Parsing in Android

     This tutorial explains you about the SAX parsing in Android. SAX (Simple API for XML) is an event-based sequential access parser API. SAX provides a mechanism for reading data from an XML document that is an alternative to that provided by the Document Object Model (DOM). Where the DOM operates on the document as a whole and takes more memory to store, SAX parsers operate on each piece of the XML document sequentially. Generally, SAX parsing is suitable more for large files.
Usually, Android applications need to call third-party service API's. We have so many data formats like json, xml, wddx, yaml, php, dump etc,. But we use mostly xml and json formats to transfer data.

XML Data Format:

XML was created to structure, store and transport data. It will be easily readable by the humans as well machines. Follow the sample XML format. I am saving this data named studentDetails.xml in  res/raw folder.

<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<no>1</no>
<name>sachin</name>
<class>Computers</class>
<phno>1234567890</phno>
<email>sachin@gmail.com</email>
</student>

<student>
<no>2</no>
<name>Ganguly</name>
<class>EEE</class>
<phno>1234567890</phno>
<email>Ganguly@gmail.com</email>
</student>

<student>
<no>3</no>
<name>Dravid</name>
<class>CSE</class>
<phno>1234567890</phno>
<email>Dravid@gmail.com</email>
</student>

<student>
<no>4</no>
<name>Laxman</name>
<class>CSIT</class>
<phno>1234567890</phno>
<email>Laxman@gmail.com</email>
</student>

<student>
<no>5</no>
<name>Kumble</name>
<class>MCA</class>
<phno>1234567890</phno>
<email>Kumble@gmail.com</email>
</student>

</students>



How to Parse XML data?

Now, we need to parse the above xml data in android. Follow the step by step process below.

First, Open or create your project.
Then, create an xml layout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:paddingLeft="10dp" >
  
  <TextView
  android:id="@+id/SNoText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />
  
  <TextView
  android:id="@+id/SNameText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:textStyle="bold" />
  
  <TextView
  android:id="@+id/SClassText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"/>
  
  <TextView
  android:id="@+id/SPhoneText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />
  
  <TextView
  android:id="@+id/SEmailText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />

</LinearLayout>



Now, start your activity code. Create an ListActivity named SaxParserDemoActivity. And follow the below code.



package com.prakash_saxparser;

import java.io.InputStream;

import java.util.ArrayList;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.app.Activity;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class SaxParserDemoActivity extends ListActivity {


      //Decalre String Arrays here

ArrayList<String> al_studentNo=new ArrayList<String>();
ArrayList<String> al_studentName=new ArrayList<String>();
ArrayList<String> al_studentClass=new ArrayList<String>();
ArrayList<String> al_studentPhno=new ArrayList<String>();
ArrayList<String> al_studentEmail=new ArrayList<String>();

SAXParserFactory spf;
SAXParser sp;
XMLReader xr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

try{
          //Getting student data from Raw folder here.
        InputStream is=getResources().openRawResource(R.raw.studentdetails);
               
        spf=SAXParserFactory.newInstance();
        sp=spf.newSAXParser();
        xr=sp.getXMLReader();
       
        MyHandler mh=new MyHandler();
        xr.setContentHandler(mh);
       
        xr.parse(new InputSource(is));
        }
        catch(Exception e){}
setListAdapter(new MyAdapter());
       
}

//Created Adapter class.

class MyAdapter extends BaseAdapter{

@Override

public int getCount() {
// TODO Auto-generated method stub
return al_studentClass.size(); 
}

@Override

public Object getItem(int arg0) {
// TODO Auto-generated method stub
return arg0;
}

@Override

public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}

@Override

public View getView(int arg0, View arg1, ViewGroup arg2) {
LayoutInflater li=(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View v=li.inflate(R.layout.saxlayout, null); //Applying layout.
//Setting data to layout.
TextView tv1=(TextView)v.findViewById(R.id.SNoText);
tv1.setText(al_studentNo.get(arg0));

TextView tv2=(TextView)v.findViewById(R.id.SNameText);
tv2.setText(al_studentName.get(arg0));

TextView tv3=(TextView)v.findViewById(R.id.SClassText);
tv3.setText(al_studentClass.get(arg0));

TextView tv4=(TextView)v.findViewById(R.id.SPhoneText);
tv4.setText(al_studentPhno.get(arg0));


TextView tv5=(TextView)v.findViewById(R.id.SEmailText);
tv5.setText(al_studentEmail.get(arg0));

return v;
}
   
    }
    //Creating MyHandler class.
    //starting......fill.......ending.....
    class MyHandler extends DefaultHandler{
    boolean is_studentNo=false;
    boolean is_studentName=false;
    boolean is_studentClass=false;
    boolean is_studentPhno=false;
    boolean is_studentEmail=false;
   
   
    @Override
    public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.startDocument();
    }
   
    @Override
    public void startElement(String uri, String localName, String name,
    Attributes attributes) throws SAXException {
    super.startElement(uri, localName, name, attributes);
    if(localName.equals("no")){
    is_studentNo=true;
    }
    else if(localName.equals("name")){
    is_studentName=true;
    }
    else if(localName.equals("class")){
    is_studentClass=true;
    }
    else if(localName.equals("phno")){
    is_studentPhno=true;
    }
    else if(localName.equals("email")){
    is_studentEmail=true;
    }
    }
   
    @Override
    public void characters(char[] ch, int start, int length)
    throws SAXException {
    // TODO Auto-generated method stub
    super.characters(ch, start, length);
    if(is_studentNo){
    al_studentNo.add(new String(ch,start,length));
    }
    else if(is_studentName){
    al_studentName.add(new String(ch,start,length));
    }
    else if(is_studentClass){
    al_studentClass.add(new String(ch,start,length));
    }
    else if(is_studentPhno){
    al_studentPhno.add(new String(ch,start,length));
    }
    else if(is_studentEmail){
    al_studentEmail.add(new String(ch,start,length));
    }
    }
   
    @Override
    public void endElement(String uri, String localName, String name)
    throws SAXException {
    // TODO Auto-generated method stub
    super.endElement(uri, localName, name);
   
    if(localName.equals("no")){
    is_studentNo=false;
    }
    else if(localName.equals("name")){
    is_studentName=false;
    }
    else if(localName.equals("class")){
    is_studentClass=false;
    }
    else if(localName.equals("phno")){
    is_studentPhno=false;
    }
    else if(localName.equals("email")){
    is_studentEmail=false;
    }
    }
   
    @Override
    public void endDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.endDocument();
    }
    }
}


Result screen:



How to get Web Service Data?
The above example shows you how to read stored file in application. But if you want to read the data from outside the application like web-services. Replace below code to above one.

//URL
String ServiceURL="http://10.0.12.1/MySampleService/Service.asmx/GetStudentData?UserID="+1;

spf=SAXParserFactory.newInstance();

      sp=spf.newSAXParser();
      xr=sp.getXMLReader();
      URL sourceUrl = new URL(ServiceURL);  
      MyHandler mh=new MyHandler();
      xr.setContentHandler(mh);
     
      xr.parse(new InputSource(sourceUrl.openStream()));

 Add internet permission in AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Enjoy coding!!!!!!!!!!

2 comments:

  1. hell tejprakash I had try many tym to consume wcf service in android but still not getting output.....
    Can i use my mobile device instead of emulator to run this type of app.....
    if yes then how it is possibe or if no then y ?

    ReplyDelete
    Replies
    1. Hi Nikhil, you can use emulator or mobile to run this kind of app. Make 'HTTP request' and display list with help of Lazy Adapter.

      Delete