Consuming a SOAP Web Service: XmlPullParser Alternative

In a previous article, Android Lists V: Accessing and Consuming a SOAP Web Service II, I discussed the various options available for parsing XML on Android and showed how to implement a SAX handler.  The SAX handler was used to parse the response of a SOAP web service into StockQuote objects for use in the ListView in the StockList application.

An alternative to using a SAX handler to parse the response is to utilize the XmlPullParser.  In this article, I’ll show how we can substitute XmlPullParser for the SAX handler that was previously used.

Despite the opposite nature of the SAX parser, a push parser, and XmlPullParser, a pull parser, they are implemented quite similarly.

The main difference between the two is that, using a pull parser, the application must request (“pull”) the remaining XML content from the XML document.  While using a push parser, the application has no ability to explicitly request the remaining data, the data is automatically pushed to the handler.

Let’s take a look at the following alternate implementation for the StockQuoteHandler:

package com.austinrasmussen.stockviewer;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;

public class StockQuoteHandler {

	private ArrayList quotes;
	private StringReader xmlReader;

	private final String STOCK = "Stock";
	private final String SYMBOL = "Symbol";
	private final String LAST = "Last";

	public StockQuoteHandler(String xml) {
		xmlReader = new StringReader(xml);
	}

	public void parse() throws XmlPullParserException, IOException {
		XmlPullParser parser = Xml.newPullParser();
		parser.setInput(xmlReader);

		// The StockQuote that is currently being parsed
		StockQuote currentQuote = null;
		// The current event returned by the parser
		int eventType = parser.getEventType();

		while (eventType != XmlPullParser.END_DOCUMENT) {
			String xmlNodeName;

			switch (eventType) {
			case XmlPullParser.START_DOCUMENT:
				quotes = new ArrayList();
				break;
			case XmlPullParser.START_TAG:
				xmlNodeName = parser.getName();
				if (xmlNodeName.equalsIgnoreCase(STOCK)) {
					// When the  element is reached, create a new
					// StockQuote.
					currentQuote = new StockQuote();
				} else if (xmlNodeName.equalsIgnoreCase(SYMBOL)) {
					currentQuote.setTickerSymbol(parser.nextText());
				} else if (xmlNodeName.equalsIgnoreCase(LAST)) {
					currentQuote
							.setQuote(Double.parseDouble(parser.nextText()));
				}
				break;
			case XmlPullParser.END_TAG:
				xmlNodeName = parser.getName();
				if (xmlNodeName.equalsIgnoreCase(STOCK)) {
					quotes.add(currentQuote);
					break;
				}
			}

			eventType = parser.next();
		}
	}

	public ArrayList getQuotes() {
		return quotes;
	}
}

The most important method in this class is clearly the parse() method.  It starts off by creating a new XmlPullParser and setting the parser to use the XML that was passed in when the StockQuoteHandler was constructed.

It then iterates through the XML document by calling the next() method on the parser and determines the current processing event by calling the getEventType() method.

Inside of this iteration, you may notice that it looks quite similar to the SAX handler.  Using the XmlPullParser, it is no longer required to capture the text of the current node (via the characters(…) method override) as was done in the SAX handler.  The text of the node that the parser is currently on can be simply retrieved using the nextText() method.

That’s really all there is to it to using the XmlPullParser!

Now, there’s just a few small changes that need to be done to the Fetch() method of the StockQuoteFetcher to use this new parsing implementation.

public List<StockQuote> Fetch()
{
	HttpTransportSE httpRequest = new HttpTransportSE(URL);

	try
    {
		httpRequest.call(SOAP_ACTION, envelope);
		SoapPrimitive response = (SoapPrimitive)envelope.getResponse();

		StockQuoteHandler quoteParser = new StockQuoteHandler(response.toString());
		quoteParser.parse();
		return quoteParser.getQuotes();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }

	return new ArrayList<StockQuote>();
}

The StockList application continues to work as it had, but now it is using a different method of parsing the response from the web service.

Tags: , , , , ,

This entry was posted on Saturday, May 7th, 2011 at 12:21 pm and is filed under Android. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

You must be logged in to post a comment.