Friday, February 1, 2013

Android a Simple SAX Parser (using web url)

Parsing data from an XML file is a very common goal in mobile applications. This tutorial will provide you with a hands on approach for reading XML data with a SAX parser. SAX is an abbreviation for “Simple API for XML”, and it is a very powerful tool for reading XML.


One of the biggest advantages that SAX parsers offer is a low memory footprint. They parse each line of XML data at a time and consequently do not need to load the entire XML document into memory prior to making the data accessible. This is a significant boost to performance, and this really becomes visible when working with large XML documents.
One of the disadvantages of using a SAX parser is that you must define an event-driven API that will respond to each element as it is received. This can become time consuming to build, but if you are willing to spend a little extra time to get it right, the outcome will be worthwhile.

As we are using internet to access web url so do not foget to use add permission to manifest of the project 
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

the MainActivity java clas should have with the following code

package com.jitesh.androidsaxparserwebfeed; import java.net.URL; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { XMLGettersSetters data; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /** * Get the view of the layout within the main layout, so that we can add * TextViews. **/ View layout = findViewById(R.id.layout); /** * Create TextView Arrays to add the retrieved data to. **/ TextView title[]; TextView artist[]; TextView country[]; TextView company[]; TextView price[]; TextView year[]; try { /** * Create a new instance of the SAX parser **/ SAXParserFactory saxPF = SAXParserFactory.newInstance(); SAXParser saxP = saxPF.newSAXParser(); XMLReader xmlR = saxP.getXMLReader(); URL url = new URL("http://www.xmlfiles.com/examples/cd_catalog.xml"); // URL // of // the // XML /** * Create the Handler to handle each of the XML tags. **/ XMLHandler myXMLHandler = new XMLHandler(); xmlR.setContentHandler(myXMLHandler); xmlR.parse(new InputSource(url.openStream())); } catch (Exception e) { System.out.println(e); } data = XMLHandler.data; /** * Makes the TextView length the size of the TextView arrays by getting * the size of the **/ title = new TextView[data.getTitle().size()]; artist = new TextView[data.getArtist().size()]; country = new TextView[data.getCountry().size()]; company = new TextView[data.getCompany().size()]; price = new TextView[data.getPrice().size()]; year = new TextView[data.getYear().size()]; /** * Run a for loop to set All the TextViews with text until the size of * the array is reached. * **/ for (int i = 0; i < data.getTitle().size(); i++) { title[i] = new TextView(this); title[i].setText("Title = " + data.getTitle().get(i)); artist[i] = new TextView(this); artist[i].setText("Artist = " + data.getArtist().get(i)); country[i] = new TextView(this); country[i].setText("Country = " + data.getCountry().get(i)); company[i] = new TextView(this); company[i].setText("Company = " + data.getCompany().get(i)); price[i] = new TextView(this); price[i].setText("Price = " + data.getPrice().get(i)); year[i] = new TextView(this); year[i].setText("Year = " + data.getYear().get(i)); ((ViewGroup) layout).addView(title[i]); ((ViewGroup) layout).addView(artist[i]); ((ViewGroup) layout).addView(country[i]); ((ViewGroup) layout).addView(company[i]); ((ViewGroup) layout).addView(price[i]); ((ViewGroup) layout).addView(year[i]); } setContentView(layout); } }

the main.xml is having layout as follows

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/layout"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello_world" android:textSize="15dp" android:gravity="center_horizontal" android:id="@+id/layout_string"/> </LinearLayout>

The Content Handler

package com.jitesh.androidsaxparserwebfeed; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class XMLHandler extends DefaultHandler { String elementValue = null; Boolean elementOn = false; public static XMLGettersSetters data = null; public static XMLGettersSetters getXMLData() { return data; } public static void setXMLData(XMLGettersSetters data) { XMLHandler.data = data; } /** * This will be called when the tags of the XML starts. **/ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { elementOn = true; if (localName.equals("CATALOG")) { data = new XMLGettersSetters(); } else if (localName.equals("CD")) { /** * We can get the values of attributes for eg. if the CD tag had an attribute( <CD attr= "band">Akon</CD> ) * we can get the value "band". Below is an example of how to achieve this. * * String attributeValue = attributes.getValue("attr"); * data.setAttribute(attributeValue); * * */ } } /** * This will be called when the tags of the XML end. **/ @Override public void endElement(String uri, String localName, String qName) throws SAXException { elementOn = false; /** * Sets the values after retrieving the values from the XML tags * */ if (localName.equalsIgnoreCase("title")) data.setTitle(elementValue); else if (localName.equalsIgnoreCase("artist")) data.setArtist(elementValue); else if (localName.equalsIgnoreCase("country")) data.setCountry(elementValue); else if (localName.equalsIgnoreCase("company")) data.setCompany(elementValue); else if (localName.equalsIgnoreCase("price")) data.setPrice(elementValue); else if (localName.equalsIgnoreCase("year")) data.setYear(elementValue); } /** * This is called to get the tags value **/ @Override public void characters(char[] ch, int start, int length) throws SAXException { if (elementOn) { elementValue = new String(ch, start, length); elementOn = false; } } }

Getters, Setters, and Logcat


package com.jitesh.androidsaxparserwebfeed; import java.util.ArrayList; import android.util.Log; /** * This class contains all getter and setter methods to set and retrieve data. * **/ public class XMLGettersSetters { private ArrayList<String> title = new ArrayList<String>(); private ArrayList<String> artist = new ArrayList<String>(); private ArrayList<String> country = new ArrayList<String>(); private ArrayList<String> company = new ArrayList<String>(); private ArrayList<String> price = new ArrayList<String>(); private ArrayList<String> year = new ArrayList<String>(); public ArrayList<String> getCompany() { return company; } public void setCompany(String company) { this.company.add(company); Log.i("This is the company:", company); } public ArrayList<String> getPrice() { return price; } public void setPrice(String price) { this.price.add(price); Log.i("This is the price:", price); } public ArrayList<String> getYear() { return year; } public void setYear(String year) { this.year.add(year); Log.i("This is the year:", year); } public ArrayList<String> getTitle() { return title; } public void setTitle(String title) { this.title.add(title); Log.i("This is the title:", title); } public ArrayList<String> getArtist() { return artist; } public void setArtist(String artist) { this.artist.add(artist); Log.i("This is the artist:", artist); } public ArrayList<String> getCountry() { return country; } public void setCountry(String country) { this.country.add(country); Log.i("This is the country:", country); } }

the screen shot of the output is given here



the code can be downloaded from the link SAX Parser

3 comments:

  1. instead of this xmlR.parse(new InputSource(url.openStream())) i used

    URL url = new URL("https://www.setindia.com");
    URLConnection urlConnectionObject = url.openConnection();
    xmlHandlerObject = new XMLHandler();
    xmlReaderObject.setContentHandler(xmlHandlerObject);
    xmlReaderObject.parse(new InputSource(urlConnectionObject.getInputStream())); //error

    what is the error
    please provide an explanation

    ReplyDelete
    Replies
    1. hi please provide me the logs even i did not understand what you are trying to parse with link https://www.setindia.com.

      the link in the blog example is http://www.xmlfiles.com/examples/cd_catalog.xml which meaningful to parse the data.

      on the first look the following code is not looking good. please investigate it they way you are writing is not appropriate.
      xmlReaderObject.parse(new InputSource(urlConnectionObject.getInputStream())); //error

      Delete
  2. Given so much info in it, These type of articles keeps the users interest in the website, and keep on sharing more ... good luck.
    Android Training in chennai | Best Android Training in chennai

    ReplyDelete