Android XML Parsing Using Sax Parser Over Http


XML Stands For Extensible Mark-up Language  that defines a set of rules for encoding documents in a format which is both human-readable , android sdk provides api called SAXParse using which you can parse the xml format data . you can also parse xml using DOM Parse but the advantage of SAX Parser Over DOM Parse is It consumes less memory than DOM.



Here In this tutorial we are going to parse the xml over http which is located at
http://api.tutorialsbuzz.com/emp/employees.xml


HTTP Request And Response Handler


Create a Class ServiceRequest the purpose of this class is to make http request and get response , there are two types of request POST and GET for which i have defined two methods inside this class
  •     MakePostRequest() .
  •     MakeGetRequest() .
Depending upon your request type make call to either of these methods

file: ServiceRequest.java
package com.tutorialsbuzz.saxparserdemo;

import java.net.URI;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class ServiceRequest {

    HttpPost httppost;
    HttpGet httpget;
    HttpEntity entity;
    HttpResponse response = null;
    HttpClient client = new DefaultHttpClient();
    URI website = null;

    String url;
    List<NameValuePair> params;

    public ServiceRequest(String url, List<NameValuePair> params) {
        this.url = url;
        this.params = params;
    }

    public String MakePostRequest() {

        try {
            website = new URI(url);
            httppost = new HttpPost();
            if (params != null) {
                httppost.setEntity(new UrlEncodedFormEntity(params));
            }
            httppost.setURI(website);
            response = client.execute(httppost);
            entity = response.getEntity();
            return EntityUtils.toString(entity);

        } catch (Exception e) {
            return e.toString();
        }

    }

    public String MakeGetRequest() {
        try {
            if (params != null) {
                String paramString = URLEncodedUtils.format(params, "utf-8");
                url += "?" + paramString;
            }
            website = new URI(url);
            httpget = new HttpGet();
            httpget.setURI(website);
            response = client.execute(httpget);
            entity = response.getEntity();

            return EntityUtils.toString(entity);

        } catch (Exception e) {
            return "some error";
        }
    }

}


SaxParser


Create a Class SAXXMLHandler and extends this class to DefaultHandler and override the startElement() , characters() and endElement() methods. here in this class we parse xml and store .

file: SAXXMLHandler.java
package com.tutorialsbuzz.saxparserdemo;

import java.util.ArrayList;
import java.util.HashMap;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXXMLHandler extends DefaultHandler {

    private String tempVal;
    ArrayList<HashMap<String, String>> empList;
    HashMap<String, String> hm;

    public SAXXMLHandler() {
        empList = new ArrayList<HashMap<String, String>>();
    }

    public ArrayList<HashMap<String, String>> getEmplist() {
        return empList;
    }

    // Event Handlers
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // reset
        tempVal = "";

        if (qName.equalsIgnoreCase("employee")) {
            // create a new instance of employee
            hm = new HashMap<String, String>();
        }
    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {
        tempVal = new String(ch, start, length);
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (qName.equalsIgnoreCase("employee")) {
            // add it to the list
            empList.add(hm);
        } else if (qName.equalsIgnoreCase("id")) {
                    hm.put("id", tempVal);
        } else if (qName.equalsIgnoreCase("name")) {
                   hm.put("name", tempVal);
        } else if (qName.equalsIgnoreCase("department")) {
                   hm.put("dept", tempVal);
        } else if (qName.equalsIgnoreCase("email")) {
                  hm.put("email", tempVal);
        }
    }
}


Create a class SAXXMLParser and  add a static method parse() which takes inputstream as parameter and returns arraylist of hasmap .

file: SAXXMLParser.java
package com.tutorialsbuzz.saxparserdemo;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.util.Log;

public class SAXXMLParser {
    public static ArrayList<HashMap<String, String>> parse(InputStream is) {

        ArrayList<HashMap<String, String>> empList = null;

        try {
            // create a XMLReader from SAXParser
            XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser()
                    .getXMLReader();
            // create a SAXXMLHandler
            SAXXMLHandler saxHandler = new SAXXMLHandler();

            // store handler in XMLReader
            xmlReader.setContentHandler(saxHandler);
            // the process starts
            xmlReader.parse(new InputSource(is));
            // get the `Employee list`
            empList = saxHandler.getEmplist();

        } catch (Exception ex) {
            Log.d("XML", "SAXXMLParser: parse() failed");
        }

        // return Employee list
        return empList;
    }
}


XML Layout


Create XML Layout file list_items.xml , this xml layout represents the row items of listview to which  display xml data .

file:list_items.xml
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.tutorialsbuzz.saxparserdemo.MainActivity" >

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"
        android:textColor="#000000"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/name"
        android:layout_below="@+id/name"
        android:text="TextView"
        android:textColor="#000000"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/dept"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="TextView"
        android:textColor="#000000" />

</RelativeLayout>

ListActivity


Create a class MainActivity and extend this class to ListActivity .
Create an inner class MyTask which extends the AsyncTask .
Inside the doInBackground() method parse the xml and finally inside the onPostExecute() method update the listview .

file: MainActivity
package com.tutorialsbuzz.saxparserdemo;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;

public class MainActivity extends ListActivity {

    ArrayList<HashMap<String, String>> empList;
    ProgressDialog PD;
    ServiceRequest service_request;
    String url="http://api.tutorialsbuzz.com/emp/employees.xml";
    String webdata;
    SAXParser saxParser;
    InputStream is;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        SAXParserFactory factory = SAXParserFactory.newInstance();

        try {
            saxParser = factory.newSAXParser();
        } catch (ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }

        new MyTask().execute();

    }

    class MyTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            PD = new ProgressDialog(MainActivity.this);
            PD.setMessage("Loading...");
            PD.setCancelable(false);
            PD.show();

        }

        @Override
        protected Void doInBackground(Void... arg0) {

            service_request = new ServiceRequest(url , null);

            webdata = service_request.MakeGetRequest();

            is = new ByteArrayInputStream(webdata.getBytes());

            empList = SAXXMLParser.parse(is);

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            String[] from = { "name", "email", "dept" };
            int[] to = { R.id.name, R.id.email, R.id.dept };

            ListAdapter adapter = new SimpleAdapter(getApplicationContext(),
                    empList, R.layout.list_items, from, to);

            setListAdapter(adapter);

            PD.dismiss();

        }
    }

}


Finally Add Internet Permission Inside the Manifest file .

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



No comments:

Post a Comment