Need help?

I'm available for remote short term contracting or consultancy work. Please check out my LinkedIn profile for more details on my experience.

Please feel free to use the form below to contact me.




Android XML SAX Parser Example

This article is going to walk you through some examples of how to use SAX to parse through XML documents, in an Android SDK environment.

There are actually 2 main ways of handling XML - SAX and DOM. The DOM parser loads the whole document into memory before it can work with it, which can be slow and uses up a lot more memory - the benefit is that you're not writing as much code. In this tutorial though, I'm going to be focusing on SAX, simply because it's the best for mobile devices, as they don't have a lot of memory. The beauty of SAX is that it goes through each element and attribute one at a time, and you can pick and choose which one you want added into memory, but you do need to write a lot more code (depending on what you want to do).

And before I forget, there is another called STaX, which is an XML pull parser, but I'm not going to get into that one.

Here is the XML file that I'm going to use for this example:


<data>
	<section id="1">bla</section>
	<area>lala</area>
</data>

And here is the Activity example:


@Override
public void onCreate(Bundle icicle) {
  super.onCreate(icicle);
  setContentView(R.layout.main);


  // start the parser and get back the Data object, which you can do whatever you want with
  Data data = _parseXml();
}

private Data _parseXml() {
  Data data = null;

  // sax stuff
  try {
    SAXParserFactory spf = SAXParserFactory.newInstance();
    SAXParser sp = spf.newSAXParser();

    XMLReader xr = sp.getXMLReader();

    DataHandler dataHandler = new DataHandler();
    xr.setContentHandler(dataHandler);

    xr.parse(new InputSource(new FileInputStream("/path/to/data.xml")));

    data = dataHandler.getData();

  } catch(ParserConfigurationException pce) {
    Log.e("SAX XML", "sax parse error", pce);
  } catch(SAXException se) {
    Log.e("SAX XML", "sax error", se);
  } catch(IOException ioe) {
    Log.e("SAX XML", "sax parse io error", ioe);
  }

  return data;
}

In the onCreate we're calling a private method which loads the SAX parser and calls our custom handler (which you'll see below in a second).

Once that's loaded and parsed, we call a method called getData to retrieve the information we collected from the XML document.

Here's the code for our handler:


public class DataHandler extends DefaultHandler {

  // booleans that check whether it's in a specific tag or not
  private boolean _inSection, _inArea;

  // this holds the data
  private Data _data;

  /**
   * Returns the data object
   *
   * @return
   */
  public String getData() {
    return _data;
  }

  /**
   * This gets called when the xml document is first opened
   *
   * @throws SAXException
   */
  @Override
  public void startDocument() throws SAXException {
    _data = new Data();
  }

  /**
   * Called when it's finished handling the document
   *
   * @throws SAXException
   */
  @Override
  public void endDocument() throws SAXException {

  }

  /**
   * This gets called at the start of an element. Here we're also setting the booleans to true if it's at that specific tag. (so we
   * know where we are)
   *
   * @param namespaceURI
   * @param localName
   * @param qName
   * @param atts
   * @throws SAXException
   */
  @Override
  public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {

    if(localName.equals("section")) {
      _inSection = true;

      _data.sectionId = atts.getValue("id");
    } else if(localName.equals("area")) {
      _inArea = true;
    }
  }

  /**
   * Called at the end of the element. Setting the booleans to false, so we know that we've just left that tag.
   *
   * @param namespaceURI
   * @param localName
   * @param qName
   * @throws SAXException
   */
  @Override
  public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
    Log.v("endElement", localName);

    if(localName.equals("section")) {
      _inSection = false;
    } else if(localName.equals("area")) {
      _inArea = false;
    }
  }

  /**
   * Calling when we're within an element. Here we're checking to see if there is any content in the tags that we're interested in
   * and populating it in the Config object.
   *
   * @param ch
   * @param start
   * @param length
   */
  @Override
  public void characters(char ch[], int start, int length) {
    String chars = new String(ch, start, length);
    chars = chars.trim();

    if(_inSection) {
      _data.section = chars;
    } else if(_inArea) {
      _data.area = chars;
    }
  }
}

The DataHandler populates our custom Data object with the data that we want - in this case we're just grabbing the section id (attribute), the section and area. It can then be retrieved by calling getData, as I did in _parseXml.

And finally here is the Data class:


public class Data {
  // I know this could be an int, but this is just to show you how it works
  public String sectionId;
  public String section;
  public String area;

  public Data() {

  }
}

There you have it - that's how you can easily use the SAX XML parser in your Android application. It probably looks a bit more intimidating to use than the DOM parser, but it's a lot faster and it's quite easy once you have a play with it.

Hope this helps some people out.


jon | January 24, 2011 | Comments (17)

Comments

http://onlinereputation.beep.com/
Comment by Nellie - May 25, 2014 @ 10:18 am
http://www.sititrentini.com
Comment by Jerrold - May 10, 2014 @ 12:42 pm
http://www.streamtorrent.com
Comment by Travis - February 04, 2014 @ 6:03 pm
http://www.jigsawconferences.co.uk/BusinessTravel/
Comment by Andrea - January 07, 2014 @ 5:53 am
Your ptosnig lays bare the truth
Comment by Cheyenne - October 17, 2012 @ 3:17 pm
What if the xml document is online?
I want to parse the temperature from Yahoo!'s weather xml located here
http://weather.yahooapis.com/forecastrss?w=2442047&u=c
Comment by Varun - August 01, 2012 @ 6:22 am
Nice Tutorial.
Comment by Wenyen.C - July 24, 2012 @ 4:57 am
Hi nice one.

Im the new to android. where can i place the xml file in my directory.

Advance thanks...
Comment by bala - June 07, 2012 @ 10:59 am
Hi,
Thanks for this helpfull blog.I am working on applications which needs lots of XML Parsing.And I use the same way as you have taught us in this blog for parsing.But my problem is that where should I save the parsed data.
Right now what I am doing is I parse the data and save that data in static ArrayList or HashMap variables.So whenever I need that data I directly uses the static variables and show to my ListView or wherever I needed.And it works fine most of the time.
But what exactly problem I am facing is when I switch to some other app like Browser so I lost my previous apps data (static variable which I initilaized by parsing XMLs).So in such cases how can I retain my app's status.

Please Help
Comment by Arun - March 31, 2012 @ 3:39 am
what imports are we supposed to use?

Plus i keep getting a
Data() is not public in android.provider.ContactsContract.RawContacts.Data; cannot be accessed from outside package
Error
Comment by Casey - February 03, 2012 @ 12:32 pm
its not working for me, cause the application throws an exception saying that the file is not found...the xml file... i put the xml file in 'assets','res','bin',.java file folder too...in the project.... still the file is unable to locate... where do i put the file?.xml file?
Comment by sumeetkhobare - December 27, 2011 @ 4:34 am
Nice Tutorial.
Comment by Avtar - December 22, 2011 @ 8:13 am
Hi thanks for the tutorial...

my xml is something like this


bla
lala


asda
qwera


how to access the both set of data, section, id and area.. currently with the above code it takes second data,id and area...
Comment by sunny - November 30, 2011 @ 5:30 pm

You shouldn't be setting

_data.section = chars;

because the characters function can be called multiple times for each element, which means your data will only get what was last passed via it. You should append the contents to a string buffer and then assign and clear in endElement.

Comment by AndyP - November 16, 2011 @ 6:32 am
Hello jon,
I am having problems with your example code.

The variable data is a Data Object in your _parseXML() method ...

Data data = null;
data = dataHandler.getData();

... and you are returning a String in your getData() method.

public String getData() {
return _data;
}

Could you explain this please?
Thank you very much!
Comment by Javier - October 14, 2011 @ 5:33 am
Hi

Good example, but how parse this
variant


bla
lala


bla2
lala2

.....
Comment by Andrey - June 27, 2011 @ 5:07 am
Hi, Nice tutorial. Short and simple. But I was wondering how would you go about retrieving the data of "section id='1'" and displaying "bla" in a textview? Is that possible?
Comment by Joel - April 28, 2011 @ 12:23 am

Name (required)
Email (will not be published) (required)
Website

captcha