Archive

Posts Tagged ‘xml’

Android XML Adventure – Parsing HTML using JSoup

February 4, 2012 22 comments

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

Another library used common for parsing HTML is JSoup.

Unlike HtmlCleaner, JSoup uses the concept of attributes as a selector to identify each node in HTML tree.

I suggest you should learn the basics syntax of JSoup selector before continue, http://jsoup.org/cookbook/extracting-data/selector-syntax

Well, we will do the same thing as previous article, we get the blog statistics using JSoup.

The syntax is like this: ” div#blog-stats ul li

Literally, it means: select the node <li> inside node <ul> , which has parent is a <div> having ID value is “blog-stats“.

Download the libary JSoup and add it as “External JARs”.

Head straight to the source code to get our desire value:

package pete.android.study;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class JSoupStudyActivity extends Activity {

	// blog url
	static final String BLOG_URL = "https://xjaphx.wordpress.com/";

    @Override
    public void onCreate(Bundle savedInstanceState) {
    	// set layout view
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // process
        try {
        	((TextView)findViewById(R.id.tv)).setText(getBlogStats());
        } catch (Exception ex) {
        	((TextView)findViewById(R.id.tv)).setText("Error");
        }
    }

    protected String getBlogStats() throws Exception {
    	String result = "";
    	// get html document structure
    	Document document = Jsoup.connect(BLOG_URL).get();
    	// selector query
    	Elements nodeBlogStats = document.select("div#blog-stats ul li");
    	// check results
    	if(nodeBlogStats.size() > 0) {
    		// get value
    		result = nodeBlogStats.get(0).text();
    	}

    	// return
    	return result;
    }
}

Remember to add INTERNET permission. Here the result on my Galaxy S II phone, which is a little chocky-cocky:

JSoup Sample

JSoup Sample

Not so much different from XPath, is it?

Cheers,

Pete Houston

Categories: Tutorials Tags: , , , , , ,

Android XML Adventure – Parsing XML using XPath

December 24, 2011 4 comments

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

XPath is a syntax to query directly to the specified tag by name or id or using any pre-defined function to detect the nodes. It’s really useful when it’s coming to parse a lot of data in the form of an array.

You might want to study some about XPath first: W3Schools – XPath Tutorials

Specifically, we will apply XPath in Android platform, there’s a library also named XPath, pre-package in Android framework. Reference to Android XPath Library.

The usage of XPath is pretty much simple:

1. Create a `InputSource` object, from a `String`, from a `InputStream`, from `Resources`, from `Assets` ….

2. Create a `XPath` object

3. Define your XPath expression, which is a `String`.

4. Evaluate above expression from `InputSource` created at step 1.

5. Query data retrieved from evaluation.

That’s it. Here go for an example, I’ll have the following XML file, `data.xml`, and put into `/res/raw` folder.

<?xml version="1.0" encoding="UTF-8"?>
<sample>
	<info>
		<title>Using XPath to parse XML</title>
		<author>Pete Houston</author>
	<list>
		<person id="1">
			<name>Pete Houston</name>
			<age>28</age>
		</person>

		<person id="2">
			<name>Nina Jones</name>
			<age>27</age>
		</person>

		<person id="3">
			<name>Yumin Hanazuki</name>
			<age>22</age>
		</person>
	</list>
	</info>
</sample>

Following above 5 steps, including display data to UI.

package pete.android.tutorial.xml.xpath;

import java.util.ArrayList;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Toast;

public class XPathStudyActivity extends ListActivity {
    // data
	ArrayList<String> mPeople = new ArrayList<String>();

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

        try {
        	parseData();
        } catch(Exception ex) {
        	Toast.makeText(this, "Exception: " + ex.getMessage(), Toast.LENGTH_LONG).show();
        }

        // pass adapter w/ data queried through XPath to ListView
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mPeople);
        setListAdapter(adapter);
    }

    private void parseData() throws Exception {
    	// create an InputSource object from /res/raw
    	InputSource inputSrc = new InputSource(getResources().openRawResource(R.raw.data));
    	// query XPath instance, this is the parser
    	XPath xpath = XPathFactory.newInstance().newXPath();
    	// specify the xpath expression
    	String expression = "//name";
    	// list of nodes queried
    	NodeList nodes = (NodeList)xpath.evaluate(expression, inputSrc, XPathConstants.NODESET);

    	Toast.makeText(this, "count: " + String.valueOf(nodes.getLength()),Toast.LENGTH_SHORT).show();
    	// if node found
    	if(nodes != null && nodes.getLength() > 0) {
    		mPeople.clear();
    		int len = nodes.getLength();
    		for(int i = 0; i < len; ++i) {
    			// query value
    			Node node = nodes.item(i);
    			mPeople.add(node.getTextContent());
    		}
    	}
    }
}

The above sample, I’ve tried to query all `name` XML tag from `data.xml` file and display on the list. Very simple usage w/ XPath library!

Have fun,
Pete Houston

Categories: Tutorials Tags: , , , , , ,

Android XML Adventure – Compare: XML Parsers

November 1, 2011 1 comment

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

I’ve already introduced you about the common Android XML Parsers:

  • SAX Parser
  • DOM
  • XMLPullParser

I thought I would give a article to compare among these parsers; however, I have found a really nice page that already made the comparison, especially about performance. So I decided to trackback this page instead of posting new article for it.

Developer.Com – Android XML Parser Performance

It’s very clear, detailed and well-explained, and you should read of it.

Cheers,

Pete Houston

Categories: Tutorials Tags: , ,

Android XML Adventure – Create & Write XML Data

October 27, 2011 7 comments

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

Have you mastered with parsing XML stuffs well?

Today, I’d like to talk about writing XML file, just like a normal Java program, there’s no differences.

Our steps are going to be:

+ First, create XML string (which is residing in memory for later use).

+ Second, write the XML string to a file, which belongs to internal storage of an Android application.

About the second step, I assume that you’ve already known how to do it. Shortly, `Context.openFileOutput()` will do the job.

For the first thing, there various ways to do; however, I’d like to introduce only most three common ways.

1. A normal String format

Understand what I mean?

	public static String writeUsingNormalOperation(Study study) {
		String format =
				"<?xml version='1.0' encoding='UTF-8'?>" +
				"<record>" +
				"	<study id='%d'>" +
				"		<topic>%s</topic>" +
				"		<content>%s</content>" +
				"		<author>%s</author>" +
				"		<date>%s</date>" +
				"	</study>" +
				"</record>";
		return String.format(format, study.mId, study.mTopic, study.mContent, study.mAuthor, study.mDate);
	}

The Good:

  • Very quick and easy.
  • Not much code or custom objects required.

The Bad:

  • Straightforwardly static string, if you want to output a list of XML tags, this way doesn’t work.
  • Easy to make mistake while making the format for output.

2. Using DOM

	public static String writeUsingDOM(Study study) throws Exception {
		Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		// create root: <record>
		Element root = doc.createElement(Study.RECORD);
		doc.appendChild(root);

		// create: <study>
		Element tagStudy = doc.createElement(Study.STUDY);
		root.appendChild(tagStudy);
		// add attr: id =
		tagStudy.setAttribute(Study.ID, String.valueOf(study.mId));

		// create: <topic>
		Element tagTopic = doc.createElement(Study.TOPIC);
		tagStudy.appendChild(tagTopic);
		tagTopic.setTextContent(study.mTopic);

		// create: <content>
		Element tagContent = doc.createElement(Study.CONTENT);
		tagStudy.appendChild(tagContent);
		tagContent.setTextContent(study.mContent);

		// create: <author>
		Element tagAuthor = doc.createElement(Study.AUTHOR);
		tagStudy.appendChild(tagAuthor);
		tagAuthor.setTextContent(study.mAuthor);

		// create: <date>
		Element tagDate = doc.createElement(Study.DATE);
		tagStudy.appendChild(tagDate);
		tagDate.setTextContent(study.mDate);

		// create Transformer object
		Transformer transformer = TransformerFactory.newInstance().newTransformer();
		StringWriter writer = new StringWriter();
		StreamResult result = new StreamResult(writer);
		transformer.transform(new DOMSource(doc), result);

		// return XML string
		return writer.toString();
	}

The Good:

  • Implementable for dynamic data output.
  • Flexible XML configuration.

The Bad:

  • Too much object creations, using a lot.
  • Performance gets worse if XML document is large.

3. Using XMLSerializer

	public static String writeUsingXMLSerializer(Study study) throws Exception {
		XmlSerializer xmlSerializer = Xml.newSerializer();
		StringWriter writer = new StringWriter();

		xmlSerializer.setOutput(writer);
		// start DOCUMENT
		xmlSerializer.startDocument("UTF-8", true);
		// open tag: <record>
		xmlSerializer.startTag("", Study.RECORD);
		// open tag: <study>
		xmlSerializer.startTag("", Study.STUDY);
		xmlSerializer.attribute("", Study.ID, String.valueOf(study.mId));

		// open tag: <topic>
		xmlSerializer.startTag("", Study.TOPIC);
		xmlSerializer.text(study.mTopic);
		// close tag: </topic>
		xmlSerializer.endTag("", Study.TOPIC);

		// open tag: <content>
		xmlSerializer.startTag("", Study.CONTENT);
		xmlSerializer.text(study.mContent);
		// close tag: </content>
		xmlSerializer.endTag("", Study.CONTENT);

		// open tag: <author>
		xmlSerializer.startTag("", Study.AUTHOR);
		xmlSerializer.text(study.mAuthor);
		// close tag: </author>
		xmlSerializer.endTag("", Study.AUTHOR);

		// open tag: <date>
		xmlSerializer.startTag("", Study.DATE);
		xmlSerializer.text(study.mDate);
		// close tag: </date>
		xmlSerializer.endTag("", Study.DATE);

		// close tag: </study>
		xmlSerializer.endTag("", Study.STUDY);
		// close tag: </record>
		xmlSerializer.endTag("", Study.RECORD);

		// end DOCUMENT
		xmlSerializer.endDocument();

		return writer.toString();
	}

The Good:

  • Not like DOM, it requires only at least two objects to create XML document.
  • The syntax is so damn easy to work with.
  • The performance is pretty good.

The Bad:

  • At this point, I’ve not faced any drawback of using this.

4. Simple Framework

Homepage: http://simple.sourceforge.net/

This is an amazing XML Serialization/De-serialization, it is really easy to use and having quite good performance on XML data structure.

However, I’m not going to talk about it here, so you might want to discover about it yourselves. Or maybe, I will give a quick look over this framework in another article.

Well, it’s end for today post, and happy learning!

Be await for the next article on the series.

Cheers,

Pete Houston

Android XML Adventure – Parsing XML Data with DOM

October 12, 2011 1 comment

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

In this article, I’d like to introduce you the concepts of parsing XML using DOM (Document Object Model).

In DOM, everything is treated like a node, as you know in data structure; and all nodes link together and form as a whole, called `Document Tree`. There’s always a node called `ROOT` which contains the links to all other child nodes. In a XML document, there is one and only one `ROOT`, often called `Root Element` or `Document Element`.

I assume that you’re already know what XML is, and what kinds of data it holds. In DOM, a node is an interface that presents all other XML objects.

So what can a `Node` in DOM be?

a DOM Node presents a XML object

a DOM Node presents a XML object

Reference to Android – DOM Node Class

That’s the concept of DOM. About how it works, to avoid lots of words to read that make you feel tiring and boring, I’ve visualized for a better explanation and presentation:

DOM - XML Parsing Process

DOM - XML Parsing Process

From `DocumentBuilderFactory`, create an `DocumentBuilder`, at this point, it needs an input for XML data (like a string or an input stream…) in order to create a `Document` that represents a DOM tree. For parsing, it starts with retrieving the very very first `RootElement`, afterward you can choose which XML tags in document to find and parse them by using `getElementByTagName()`.

Have you understood how DOM works for now? Let’s go for a practice, we will use the input XML from previous article to parse. Having the same layout and main application interface, we just need to update the `StudyParser.java` implementing DOM methods.


package pete.android.study.parser;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import pete.android.study.data.Study;

public class StudyParser {
	public static Study parse(InputStream is) {
		// create new Study object to hold data
		Study study = null;

		try {
			// init Study object
			study = new Study();
			// create Document object
			Document xmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
			// get `root` Element, the first thing always should be done!!!
			Element root = xmlDoc.getDocumentElement();
			// collect child tags need to be parsed <study>
			NodeList listStudyNodes = root.getElementsByTagName(Study.STUDY);
			// iterate through list nodes of <study> tag
			for(int i = 0; i < listStudyNodes.getLength(); ++i) {
				// get current node
				Node curNode = listStudyNodes.item(i);
				// this tag is <study>, get `id` attribute first
				study.mId = Integer.parseInt( ((Attr)(curNode.getAttributes().item(0))).getValue() );

				// get all child tags inside <study>
				NodeList listChilds = curNode.getChildNodes();
				for(int j = 0; j < listChilds.getLength(); ++j) {
					// get a child
					Node child = listChilds.item(j);
					// if this node is ELEMENT type
					if(child.getNodeType() == Node.ELEMENT_NODE) {
						// get element name
						String childName = child.getNodeName();
						// get element text content
						String childValue = ((Element)child).getTextContent();
						// if this tag is <topic>
						if(Study.TOPIC.equalsIgnoreCase(childName)) {
							study.mTopic = childValue;
						}
						// if this tag is <content>
						else if(Study.CONTENT.equalsIgnoreCase(childName)) {
							study.mContent = childValue;
						}
						// if this tag is <author>
						else if(Study.AUTHOR.equalsIgnoreCase(childName)) {
							study.mAuthor = childValue;
						}
						// if this tag is <date>
						else if(Study.DATE.equalsIgnoreCase(childName)) {
							study.mDate = childValue;
						}
					}
				}
			}
		// of course, handling exception
		} catch (ParserConfigurationException e) {
			study = null;
		} catch (SAXException e) {
			study = null;
		} catch (IOException e) {
			study = null;
		}

		// return Study object
		return study;
	}
}

Reading the comment in the source code for inner-sight explanation.

These are some notes I’d suggest you when implementing DOM method:

1. A `Node` can re-present any XML object, so always check `Node`’s type before using it.

2. Always convert `Node` to its correct type for better commands (methods, properties).

3. If XML document is really deep (lots of childs’ of child tag), I suggest not to use DOM since it would really reduce the performance, since it needs time to construct and search for every single node.

4. If you use DOM a lot, always remember to refer to Developers’ API (Java SE 7 or Android DOM Reference).

OK! It’s done for now, try to practice as much as possible to learn it. I’ve just created and showed you the way, the fundamentals out of it. You need to keep walking by yourself if you want to study more about DOM.

Good luck and see you in the next article!

Cheers,

Pete Houston

Android XML Adventure – Parsing XML Data with SAXParser

October 9, 2011 15 comments

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

Hope you’ve already known what XML is in previous article `What is the “Thing” called XML?`.

At the start of the series, I will talk about how to parse XML data. Why parsing first? Well, it’s because most of the applications tend to parse XML data from other sources, like RSS, which is very common.

There are many ways to parse XML file in Android, however, the most three common methods are:

  1. SAXParser
  2. DOM
  3. XmlPullParser

I’ll talk about SAXParser in this article.

For a quick and easy understandings, I’ve created this flow-chart to describe how SAX-Parser works.

How SAX-Parser works!

How SAX-Parser works!

All the elements in XML document will be parsed through a ContentHandler with five pre-defined methods handling actions taken.

Class Overview

This is the main interface that most SAX applications implement: if the application needs to be informed of basic parsing events, it implements this interface and registers an instance with the SAX parser using the setContentHandler method. The parser uses the instance to report basic document-related events like the start and end of elements and character data.

The order of events in this interface is very important, and mirrors the order of information in the document itself. For example, all of an element’s content (character data, processing instructions, and/or subelements) will appear, in order, between the startElement event and the corresponding endElement event.

This interface is similar to the now-deprecated SAX 1.0 DocumentHandler interface, but it adds support for Namespaces and for reporting skipped entities (in non-validating XML processors).

(@Quote from: http://developer.android.com/reference/org/xml/sax/ContentHandler.html)

I guess the picture I drew above explains everything. Let’s head to work.

First, we need a sample XML file, I called it: “record.xml” and put it under “assets” directory, using as assets.

<?xml version="1.0" encoding="UTF-8"?>
<record>
	<study id="1">
		<topic>SAX Parser</topic>
		<content>Learn how to parse XML using SAXParser</content>
		<author>Pete Houston</author>
		<date>02-Oct-2011</date>
	</study>
</record>

We will use SAX-Parser to parse these data and display on a TextView.

The data we need: [ study id, topic, content, author, date ], I store them as an entity called “Study“, `Study.java`.

package pete.android.study.data;

public class Study {
	public int mId;
	public String mTopic;
	public String mContent;
	public String mAuthor;
	public String mDate;

	public static final String STUDY = "study";
	public static final String ID = "id";
	public static final String TOPIC = "topic";
	public static final String CONTENT = "content";
	public static final String AUTHOR = "author";
	public static final String DATE = "date";}

Great, we’ve done half of the job. Next, we need a ContentHandler that does the job of parsing every single elements in XML document, called it “StudyHandler.java“:

package pete.android.study.parser;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import pete.android.study.data.Study;

/*
 * class StudyHandler *
 */
public class StudyHandler extends DefaultHandler {

	// members
	private boolean isTopic;
	private boolean isContent;
	private boolean isAuthor;
	private boolean isDate;
	// 'Study' entity to parse
	private Study mStudy;

	// 'getter' is enough
	public Study getStudy() {
		return mStudy;
	}

	/*
	 * (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#startDocument()
	 */
	@Override
	public void startDocument() throws SAXException {
		// create new object
		mStudy = new Study();
	}

	/*
	 * (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#endDocument()
	 */
	@Override
	public void endDocument() throws SAXException {
		// nothing we need to do here
	}

	/*
	 * (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
	 */
	@Override
	public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
							throws SAXException {
		// if this element value equals "study"
		if(localName.equals(Study.STUDY)) {
			// get id right away
			mStudy.mId = Integer.parseInt(atts.getValue(Study.ID));
		}
		// if this element value equals "topic"
		else if(localName.equals(Study.TOPIC)) {
			// mark current element is "topic"
			isTopic = true;
		}
		// if this element value equals "content"
		else if(localName.equals(Study.CONTENT)) {
			// mark current element is "content"
			isContent = true;
		}
		// if this element value equals "author"
		else if(localName.equals(Study.AUTHOR)) {
			// mark current element is "author"
			isAuthor = true;
		}
		// if this element value equals "date"
		else if(localName.equals(Study.DATE)) {
			// mark current element is "date"
			isDate = true;
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public void endElement(String namespaceURI, String localName, String qName) throws SAXException {

		if(localName.equals(Study.STUDY)) {
		    // already get the attribute "id", nothing needs to do here
		}
		// if this element value equals "topic"
		else if(localName.equals(Study.TOPIC)) {
			// uncheck marking
		    isTopic = false;
		}
		// if this element value equals "topic"
		else if(localName.equals(Study.CONTENT)) {
			// uncheck marking
			isContent = false;
		}
		// if this element value equals "topic"
		else if(localName.equals(Study.AUTHOR)) {
			// uncheck marking
			isAuthor = false;
		}
		// if this element value equals "topic"
		else if(localName.equals(Study.DATE)) {
			// uncheck marking
			isDate = false;
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
	 */
	@Override
	public void characters(char ch[], int start, int length) {
		// get all text value inside the element tag
		String chars = new String(ch, start, length);
	    chars = chars.trim(); // remove all white-space characters

	    // if this tag is "topic", set "topic" value
	    if(isTopic) mStudy.mTopic = chars;
	    // if this tag is "content", set "content" value
	    else if(isContent) mStudy.mContent = chars;
	    // if this tag is "author", set "author" value
	    else if(isAuthor) mStudy.mAuthor = chars;
	    // if this tag is "date", set "date" value
	    else if(isDate) mStudy.mDate = chars;
	}
}

There we go a data handler done. Basically, that’s enough; however, for simplicity, I’d like to create an utility class that handles the whole parsing stuffs, called “StudyParser.java“:

package pete.android.study.parser;

import java.io.InputStream;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.util.Log;

import pete.android.study.data.Study;

public class StudyParser {

	public static Study parse(InputStream is) {
		Study study = null;
		try {
			// create a XMLReader from SAXParser
			XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
			// create a StudyHandler too
			StudyHandler studyHandler = new StudyHandler();
			// apply handler to the XMLReader
			xmlReader.setContentHandler(studyHandler);
			// the process starts
			xmlReader.parse(new InputSource(is));
			// get the target `Study`
			study = studyHandler.getStudy();

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

		// return Study we found
		return study;
	}
}

OK! So in main program, just giving a static call to “StudyParser.parse()” will return us a “Study” object from input XML.
Here my main program, you can just create any program you like. Mine having a TextView to display result is so enough for demonstration.

package pete.android.study;

import java.io.IOException;

import pete.android.study.data.Study;
import pete.android.study.parser.StudyParser;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class Main extends Activity {
    TextView tvStudy;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tvStudy = (TextView)findViewById(R.id.text);
        Study study = null;
        try {
			study = StudyParser.parse(getAssets().open("record.xml"));
		} catch (IOException e) {
			Log.d("XML","onCreate(): parse() failed");
			return;
		}

		String output = "";
		output += "Study ID: " + study.mId + "\n";
		output += "Topic: " + study.mTopic + "\n";
		output += "Content: " + study.mContent + "\n";
		output += "Author: " + study.mAuthor + "\n";
		output += "Date: " + study.mDate + "\n";

		tvStudy.setText(output);
    }
}

And this is the output result:

SAX-Parser Result

SAX-Parser Result

The data displays as expected!

Simple enough with SAX-Parser?

If you’re beginner or newbie, just read this article slowly and don’t skim, and you will understand it.

There are still more about SAX-Parser, however, I just guide you the most common usage and the most simple concept of parsing XML data using SAX-Parser. You will find more by Googling, I believe!

See you in the next article!!!

Cheers,

Pete Houston

Android XML Adventure – What is the “Thing” called XML?

October 9, 2011 1 comment

Currently I’m working on XML Data Storage for Android Application. It’s quite interesting! So I’ve thought to make it into series.

– What is the thing called XML?

Extensible Markup Language (XML) is a set of rules for encoding documents in machine-readable form. It is defined in the XML 1.0 Specification[4] produced by the W3C, and several other related specifications, all gratis open standards.[5]

The design goals of XML emphasize simplicity, generality, and usability over the Internet.[6] It is a textual data format with strong support via Unicode for the languages of the world. Although the design of XML focuses on documents, it is widely used for the representation of arbitrary data structures, for example in web services.

Many application programming interfaces (APIs) have been developed that software developers use to process XML data, and several schema systems exist to aid in the definition of XML-based languages.

As of 2009[update], hundreds of XML-based languages have been developed,[7] including RSS, Atom, SOAP, and XHTML. XML-based formats have become the default for most office-productivity tools, including Microsoft Office (Office Open XML), OpenOffice.org (OpenDocument), and Apple‘s iWork.[8]

(Quoted from Wikipedia: http://en.wikipedia.org/wiki/XML)

– As you see that, XML is really useful and applicable everywhere throughout the Internet nowadays, and you’d better know more about it.

– In Android, XML is used for resource planning like layout, strings (localization), … or the pre-defined SharedPreferences, or to be used as custom database…

– In this series “Android XML Adventure“, I will talk to you about the way how we can handle XML file in Android.

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

Be await for me, this series will make you fall in love XML for real 🙂

Cheers,

Pete Houston