According to Android documentation, XmlPullParser is the efficient and maintainable way to parse XML in Android. In this article, we will parse xml data using XmlPullParser and load that data into a listview. Since xml parsing is a complex and time consuming ( depends on the xml data ) process, we are doing it in a non ui thread using AsyncTask object.
Our XML data contain a set of countries with their name, capital, path to flag image, language, currency and currency code. After parsing, the country details and the flag image will be displayed in listview using a custom layout.
This application is developed in Eclipse ( 4.2.0 ) with ADT plugin ( 20.0.3 ) and Android SDK ( R20.0.3 ) .
1. Create an Android application project namely “ListViewWithXMLPullParser”
2. Design application launcher icon
3. Create a blank activity to define MainActivity class
4. Enter MainActivity details
5. Create a new folder namely drawable under the folder res
6. Download and extract the given below zip file to the drawable folder

7. Update the file res/values/strings.xml
<resources> <string name="app_name">ListViewWithXMLPullParser</string> <string name="hello_world">Hello world!</string> <string name="menu_settings">Settings</string> <string name="title_activity_main">XmlPullParser Demo</string> <string name="str_iv_flag">Flag</string> </resources>
8. Update the layout of the MainActivity class in the file res/layout/activity_main.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" > <ListView android:id="@+id/lv_countries" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:context=".MainActivity" /> </RelativeLayout>
9. Create a layout for the listview items in the file res/layout/lv_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/tv_country" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:textSize="20dp" /> <ImageView android:id="@+id/iv_flag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_country" android:layout_centerVertical="true" android:padding="4dp" android:contentDescription="@string/str_iv_flag" /> <TextView android:id="@+id/tv_country_details" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/iv_flag" android:layout_below="@id/tv_country" /> </RelativeLayout>
10.Create a class, to parse the xml data using XmlPullParser
package in.wptrafficanalyzer.listviewwithxmlpullparser; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.util.Xml; public class CountryXmlParser { private static final String ns = null; /** This is the only function need to be called from outside the class */ public List<HashMap<String, String>> parse(Reader reader) throws XmlPullParserException, IOException{ try{ XmlPullParser parser = Xml.newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(reader); parser.nextTag(); return readCountries(parser); }finally{ } } /** This method read each country in the xml data and add it to List */ private List<HashMap<String, String>> readCountries(XmlPullParser parser) throws XmlPullParserException,IOException{ List<HashMap<String, String>> list = new ArrayList<HashMap<String,String>>(); parser.require(XmlPullParser.START_TAG, ns, "countries"); while(parser.next() != XmlPullParser.END_TAG){ if(parser.getEventType() != XmlPullParser.START_TAG){ continue; } String name = parser.getName(); if(name.equals("country")){ list.add(readCountry(parser)); } else{ skip(parser); } } return list; } /** This method read a country and returns its corresponding HashMap construct */ private HashMap<String, String> readCountry(XmlPullParser parser) throws XmlPullParserException, IOException{ parser.require(XmlPullParser.START_TAG, ns, "country"); String countryName = parser.getAttributeValue(ns, "name"); String flag = parser.getAttributeValue(ns, "flag"); String language=""; String capital=""; String currencyCode=""; String currency=""; while(parser.next() != XmlPullParser.END_TAG){ if(parser.getEventType() != XmlPullParser.START_TAG){ continue; } String name = parser.getName(); if(name.equals("language")){ language = readLanguage(parser); }else if(name.equals("capital")){ capital = parser.getAttributeValue(ns, "city"); readCapital(parser); }else if(name.equals("currency")){ currencyCode = parser.getAttributeValue(ns, "code"); currency = readCurrency(parser); }else{ skip(parser); } } String details = "Language : " + language + "\n" + "Capital : " + capital + "\n" + "Currency : " + currency + "(" + currencyCode + ")"; HashMap<String, String> hm = new HashMap<String, String>(); hm.put("country", countryName); hm.put("flag", flag); hm.put("details",details); return hm; } /** Process language tag in the xml data */ private String readLanguage(XmlPullParser parser) throws IOException, XmlPullParserException { parser.require(XmlPullParser.START_TAG, ns, "language"); String language = readText(parser); return language; } /** Process Capital tag in the xml data */ private void readCapital(XmlPullParser parser) throws IOException, XmlPullParserException { parser.require(XmlPullParser.START_TAG, ns, "capital"); parser.nextTag(); } /** Process Currency tag in the xml data */ private String readCurrency(XmlPullParser parser) throws IOException, XmlPullParserException { parser.require(XmlPullParser.START_TAG, ns, "currency"); String currency = readText(parser); return currency; } /** Getting Text from an element */ private String readText(XmlPullParser parser) throws IOException, XmlPullParserException{ String result = ""; if(parser.next()==XmlPullParser.TEXT){ result = parser.getText(); parser.nextTag(); } return result; } private void skip(XmlPullParser parser) throws XmlPullParserException, IOException { if (parser.getEventType() != XmlPullParser.START_TAG) { throw new IllegalStateException(); } int depth = 1; while (depth != 0) { switch (parser.next()) { case XmlPullParser.END_TAG: depth--; break; case XmlPullParser.START_TAG: depth++; break; } } } }
11. Update the MainActivity class in the file src/in/wptrafficanalyzer/listviewwithxmlpullparser/MainActivity.java
package in.wptrafficanalyzer.listviewwithxmlpullparser; import java.io.StringReader; import java.util.HashMap; import java.util.List; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** This is the XML data to be parsed */ String xmlData = "<countries>" + "<country name='India' flag='"+Integer.toString(R.drawable.india) +"'>" + "<language>Hindi</language>" + "<capital city='New Delhi' />" + "<currency code='INR'>Indian Rupee</currency>" + "</country>" + "<country name='Pakistan' flag='"+Integer.toString(R.drawable.pakistan) +"'>" + "<language>Urdu</language>" + "<capital city='Islamabad' />" + "<currency code='PKR'>Pakistani Rupee</currency>" + "</country>" + "<country name='Sri Lanka' flag='"+Integer.toString(R.drawable.srilanka) +"'>" + "<language>Sinhala</language>" + "<capital city='Sri Jayawardenapura Kotte' />" + "<currency code='LKR'>Sri Lankan Rupee</currency>" + "</country>" + "<country name='China' flag='"+Integer.toString(R.drawable.china) +"'>" + "<language>Chineese</language>" + "<capital city='Beijing' />" + "<currency code='CNY'>Renminbi</currency>" + "</country>" + "<country name='Bangladesh' flag='"+Integer.toString(R.drawable.bangladesh) +"'>" + "<language>Bangla</language>" + "<capital city='Dhaka' />" + "<currency code='BDT'>Taka</currency>" + "</country>" + "<country name='Nepal' flag='"+Integer.toString(R.drawable.nepal) +"'>" + "<language>Nepal Bhasa</language>" + "<capital city='Kathmandu' />" + "<currency code='NPR'>Nepalese rupee</currency>" + "</country>" + "<country name='Afghanistan' flag='"+Integer.toString(R.drawable.afghanistan) +"'>" + "<language>Dari Persian</language>" + "<capital city='Kabul' />" + "<currency code='AFN'>Afghani</currency>" + "</country>" + "<country name='North Korea' flag='"+Integer.toString(R.drawable.nkorea) +"'>" + "<language>Korean</language>" + "<capital city='Pyongyang' />" + "<currency code='KPW'>North Korean won</currency>" + "</country>" + "<country name='South Korea' flag='"+Integer.toString(R.drawable.skorea) +"'>" + "<language>Korean</language>" + "<capital city='Seoul' />" + "<currency code='KRW'>South Korean won</currency>" + "</country>" + "<country name='Japan' flag='"+Integer.toString(R.drawable.japan) +"'>" + "<language>Japanese</language>" + "<capital city='Tokyo' />" + "<currency code='JPY'>Yen</currency>" + "</country>" + "</countries>"; /** The parsing of the xml data is done in a non-ui thread */ ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask(); /** Start parsing xml data */ listViewLoaderTask.execute(xmlData); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } private class ListViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter>{ /** Doing the parsing of xml data in a non-ui thread */ @Override protected SimpleAdapter doInBackground(String... xmlData) { StringReader reader = new StringReader(xmlData[0]); CountryXmlParser countryXmlParser = new CountryXmlParser(); List<HashMap<String, String>> countries = null; try{ /** Getting the parsed data as a List construct */ countries = countryXmlParser.parse(reader); }catch(Exception e){ Log.d("Exception",e.toString()); } /** Keys used in Hashmap */ String[] from = { "country","flag","details"}; /** Ids of views in listview_layout */ int[] to = { R.id.tv_country,R.id.iv_flag,R.id.tv_country_details}; /** Instantiating an adapter to store each items * R.layout.listview_layout defines the layout of each item */ SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), countries, R.layout.lv_layout, from, to); return adapter; } @Override protected void onPostExecute(SimpleAdapter adapter) { /** Getting a reference to listview of main.xml layout file */ ListView listView = ( ListView ) findViewById(R.id.lv_countries); /** Setting the adapter containing the country list to listview */ listView.setAdapter(adapter); } } }
12. Screenshot of the application
13. Download

14. Reference
http://developer.android.com/guide/index.html

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in
You can hire me on hourly basis or on project basis for Android applications development.
For hiring me, please mail your requirements to info@wptrafficanalyzer.in.
My other blogs
store4js.blogspot.com
Nice tutorial. Keep it up buddy!
very nice code,thank u