Rss Reader Android App Tutorial 3: Parse XML in Android

On June 23, 2013, in Android, by James Liu

In the previous tutorial about Rss Reader Android app, I gave the example code about how to get the data from website using AsyncTask. After we get the data, we have to read it and convert the format to server our app. XML is the standard data format for RSS. In this android example, I will show you how to parse XML in Android. If you are first time to read this post, I think you also are interested in reading the these two examples:

Analyze Rss Feed Data Before Parsing in Android

First of all, let’s see what the rss feed data looks like. It is necessary before we start to parse the XML in Android. From the rss feed data, we will find which fields we will extract. Our parser in Android will get the data from those fields and ignores the rest. The following part is what we will parsed in our Rss Reader example. Each post to my website, jmsliu.com, is shown in the feed as an “item” tag.

<item>
<title>
iPhone Rss Reader App IOS Tutorial 2: HTTP Network Programming in IOS
</title>
<link>http://jmsliu.com/1123/iphone-rss-reader-app-ios-tutorial-2-http-network-programming-in-ios.html</link>
<comments>http://jmsliu.com/1123/iphone-rss-reader-app-ios-tutorial-2-http-network-programming-in-ios.html#comments</comments>
<pubDate>Sat, 15 Dec 2012 11:12:03 +0000</pubDate>
<dc:creator>James</dc:creator>
<category>
<!&#91;CDATA&#91; iPhone iPad Object-C &#93;&#93;>
</category>
<category>
<!&#91;CDATA&#91; IOS Programming &#93;&#93;>
</category>
<guid isPermaLink="false">http://jmsliu.com/?p=1123</guid>
<description>
<!&#91;CDATA&#91;
To create a complete rss reader iphone app, http request and response are both necessary modules. Website, for example, WordPress powered website, usually provides rss feed feature. Hence, using our rss reader iphone app can easily get the rss feed contents from Http request. HTTP network programming in IOS is very simple. NSURLConnection class and &#91;...&#93;
&#93;&#93;>
</description>
<wfw:commentRss>http://jmsliu.com/1123/iphone-rss-reader-app-ios-tutorial-2-http-network-programming-in-ios.html/feed</wfw:commentRss>
<slash:comments>0</slash:comments>
</item>

Using ExpatPullParser to Parse XML in Android

To parse XML data format in Android, XmlPullParser is the recommended XML parse engine by Android developer site. It can parse XML in an efficient and maintainable way on Android. Besides this, we can also choose KXmlParser via XmlPullParserFactory.newPullParser() or ExpatPullParser via Xml.newPullParser(). Either xml parser can work well. In the Android developer site, it already give an example to show how to parse xml by ExpatPullParser. To give your more valuable Android example, I will use the recommended XML parser, XmlPullParser, to show you how to parse XML data in Android.

XmlPullParser makes the parsing job much easier. Generally, there are only several steps. Here is the simplified version:

XmlPullParserFactory factory = XmlPullParserFactory
		.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(is, null);

int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
	if (eventType == XmlPullParser.START_DOCUMENT) {
            //parsing start
	} else if (eventType == XmlPullParser.START_TAG) {
            //find a starting tag
	} else if (eventType == XmlPullParser.END_TAG) {
            //find a ending tag
	} else if (eventType == XmlPullParser.TEXT) {
	    //find text between tag
	}

	eventType = xpp.next();
}

The following code is my RSS Reader Example code. It is the subclass of AsyncTask. If you are not familiar with AsyncTask, you can check this Android example, AsyncTask Multi-thread Android Example. Inside doInBackground function, I am doing two jobs:

  • Loading Rss Data via HttpURLConnection
  • Parse XML via XmlPullParser

In parsing XML part, I am using XmlPullParser extract the title, date and link of the post from XML data. You can pay attention on the code after the comment “parse xml after getting the data”. Let’s see the source code example.

	private class RssDataController extends AsyncTask<String, Integer, ArrayList<PostData>>{
		private RSSXMLTag currentTag;

		@Override
		protected ArrayList<PostData> doInBackground(String... params) {
			// TODO Auto-generated method stub
			String urlStr = params[0];
			InputStream is = null;
			ArrayList<PostData> postDataList = new ArrayList<PostData>();
			try {
				URL url = new URL(urlStr);
				HttpURLConnection connection = (HttpURLConnection) url
						.openConnection();
				connection.setReadTimeout(10 * 1000);
				connection.setConnectTimeout(10 * 1000);
				connection.setRequestMethod("GET");
				connection.setDoInput(true);
				connection.connect();
				int response = connection.getResponseCode();
				Log.d("debug", "The response is: " + response);
				is = connection.getInputStream();

				// parse xml after getting the data
				XmlPullParserFactory factory = XmlPullParserFactory
						.newInstance();
				factory.setNamespaceAware(true);
				XmlPullParser xpp = factory.newPullParser();
				xpp.setInput(is, null);

				int eventType = xpp.getEventType();
				PostData pdData = null;
				SimpleDateFormat dateFormat = new SimpleDateFormat(
						"EEE, DD MMM yyyy HH:mm:ss");
				while (eventType != XmlPullParser.END_DOCUMENT) {
					if (eventType == XmlPullParser.START_DOCUMENT) {

					} else if (eventType == XmlPullParser.START_TAG) {
						if (xpp.getName().equals("item")) {
							pdData = new PostData();
							currentTag = RSSXMLTag.IGNORETAG;
						} else if (xpp.getName().equals("title")) {
							currentTag = RSSXMLTag.TITLE;
						} else if (xpp.getName().equals("link")) {
							currentTag = RSSXMLTag.LINK;
						} else if (xpp.getName().equals("pubDate")) {
							currentTag = RSSXMLTag.DATE;
						}
					} else if (eventType == XmlPullParser.END_TAG) {
						if (xpp.getName().equals("item")) {
							// format the data here, otherwise format data in
							// Adapter
							Date postDate = dateFormat.parse(pdData.postDate);
							pdData.postDate = dateFormat.format(postDate);
							postDataList.add(pdData);
						} else {
							currentTag = RSSXMLTag.IGNORETAG;
						}
					} else if (eventType == XmlPullParser.TEXT) {
						String content = xpp.getText();
						content = content.trim();
						Log.d("debug", content);
						if (pdData != null) {
							switch (currentTag) {
							case TITLE:
								if (content.length() != 0) {
									if (pdData.postTitle != null) {
										pdData.postTitle += content;
									} else {
										pdData.postTitle = content;
									}
								}
								break;
							case LINK:
								if (content.length() != 0) {
									if (pdData.postLink != null) {
										pdData.postLink += content;
									} else {
										pdData.postLink = content;
									}
								}
								break;
							case DATE:
								if (content.length() != 0) {
									if (pdData.postDate != null) {
										pdData.postDate += content;
									} else {
										pdData.postDate = content;
									}
								}
								break;
							default:
								break;
							}
						}
					}

					eventType = xpp.next();
				}
				Log.v("tst", String.valueOf((postDataList.size())));
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (XmlPullParserException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return postDataList;
		}

		@Override
		protected void onPostExecute(ArrayList<PostData> result) {
			// TODO Auto-generated method stub
			for (int i = 0; i < result.size(); i++) {//ignore this comment >
				listData.add(result.get(i));
			}

			postAdapter.notifyDataSetChanged();
		}
	}

After parsing the xml, an ArrayList will be returned. Inside onPostExecute function, I will update the data list with new data which is extraced from XML. As a result, posts on my website will be shown in the ListView.

website rss feed in ListView

It seems there are only 5 posts. That is because I set my website to return 5 post in Rss Feed for each request.

Next Tutorial Drag to Refresh in ListView

In most ListView based content apps, they are using pull to refresh feature to update the content. In android example Tutorial 4, I will show to add drag and pull to refresh feature in the ListView app.

Go to next tutorial: Drag to Refresh in ListView Android Example

Get The Full Source Code

You can get the full source code of this project. With the source code, you can do any changes and use the project in any of your projects.
Go To Tutorial 5 And Get The Source Code

Tagged with:  

92 Responses to “Rss Reader Android App Tutorial 3: Parse XML in Android”

  1. Vladyslav says:

    Can I see all source code of RssDataController.java.Eclipse says about a lot errors.

    Sorry my bad english

  2. James says:

    Hi Vladyslav,

    This is the whole source code of RssDataController.java. This android tutorial example is showing you how to Parse XML in Android. I just give the main part of the source code. If you want to get the whole project, please keep reading the tutorial 4 and tutorial 5.

    Thanks

  3. Paul says:

    Thank you for your good lessons. But I have question about this. Where you imported the RSSXMLTag ?

  4. Henry says:

    Hi,

    How did you implemented the add method for listData and notifyDataSetChanged?
    Nice tutorial!

    • James says:

      Hi, Henry,

      Please check onPostExecute function. In this function, I will add the data in listData, which is a class variable. So it is visible in inner class. After that, I will call postAdapter.notifyDataSetChanged(). This will let adapter update the view basing on new listData.

      Thanks

  5. Henry says:

    Thank you for your prompt response.

    As far as I know, “listData” has not an “add” method that can be implemented.

    Regarding postAdapter, where did you defined it?
    Your example does not work to me because of that.

    Any help is appreciated.

    • James says:

      Hi Henry,

      This the No.3 tutorials among the whole tutorial. You’d better to go through the whole serial tutorials. The source code I posted in the tutorial are working properly.

      In this example, the main purpose is demonstrating how to get data from internet and parse the xml in a separate the thread. And it doesn’t cover the whole project.

      My advance is you’d better keep reading the reset of tutorials.

      Thanks

  6. Henry says:

    Thank you!

    I had to change minor issues and now it works great.

  7. Mujeeb says:

    Hi,

    I’m not able to find this class “RSSXMLTag”.

    code is showing me the errors on these lines.

    private RSSXMLTag currentTag;
    currentTag = RSSXMLTag.IGNORETAG;

    listData.add(result.get(i));
    postAdapter.notifyDataSetChanged();

    If followed all ur examples but couldn’t find these.
    Please help me out.

    Thanks.

    • Mujeeb says:

      i’m able to fix RSSXMLTag issue but still not able to resolve these …

      listData.add(result.get(i));
      postAdapter.notifyDataSetChanged();

    • James says:

      This example is a partial code, which show you how to parse the xml. To get the whole project code, you have to go through all the tutorials.

      Thanks

  8. prasad says:

    What is postAdapter here and where is it defined? I fixed everything else but could fix this. also i went through the next 2 tutorials but couldnt find it. Thanks

    • James says:

      Hi Prasad,

      postAdapter is a class variable to render the list item. In tutorial 1, it is implemented as local variable, ArrayAdapter itemAdapter.

      If you want to get the full project source, please check tutorial 5.

      Thanks
      James

  9. Boukhsibi says:

    I bought your app and I would like to rss feed with images and text in a listview see that is possible.
    all type of rss is displayed??

    • James says:

      Hi Boukhsibi,

      Image is not specified in Rss 1.1 Standard. In my example, I remain the image space for customized needs. If you customize your rss to contain the image, you need to change the code to load your image link in your customized rss data.

      Thanks
      James

  10. BM says:

    Hi James,

    I am Beginner of android Developer.
    I like your Android Rss Reader Example 1 but i don’t understand this example 2 and 3. I don’t understand how to connect MainActivity ListView. Can i get sample project or sample code.
    Thank for support 🙂

  11. Madhur says:

    Where to put the code of RssDataController.??
    And where we have to put the url of our feed??

    • James says:

      Hello,

      In my example, I define it as inner private class. Inner class is a basic knowledge in Java.

      When you check the class souce code, you can define your url outside of the class. When you call this class to download your rss feed, you just instantiate a class object, and pass your url inside.

      Best Regards
      James

      • Madhur says:

        I have pasted this in MainActivity. But then i got ListView And postAdpter error.
        I solved the listView error. But post Adapter cannot be resolved. I did not find any variable named “postAdapter”.
        So I changed it to “PostItemAdapter”, then it can work but it is giving error.. “You can not put nonStatic variable in Static class” Something like this only.. I forget the exact statement…

  12. Madhur says:

    Ohk.. i am able to solve all the errors. But when i run the app,it does not parse my feeds and shows the local feed. i.e. “Post 1 Title : Title”

  13. Nikhil Lohia says:

    The tutorial was a great one until this one. The first 2 steps went like cream and I could easily implement them.
    I got stuck at this function

    @Override
    protected void onPostExecute(ArrayList result) {
    // TODO Auto-generated method stub
    for (int i = 0; i < result.size(); i++) {
    listData.add(result.get(i));
    }

    postAdapter.notifyDataSetChanged();
    }

    Can you please explain how to go through this? I am getting errors on these line like everyone else.
    "postAdapter" – where is it?
    and which "listData" are you talking about.

    Your tutorial was so good until this point. Please help further.

  14. Shaikh says:

    The app not working, error at the beginning ‘Unfortunately, APP stop working

  15. Keen says:

    Hello, Pls does this work with feedburner feed?

    I can’t load feeds using my url

    http://feeds.feedburner.com/KeendevTechnologiesBlog?format=xml

    Any help?

    Thanks

  16. Lasantha says:

    Great article.. Thanks a lot for sharing the knowledge..

  17. Bhushan Gautam says:

    Hi i check your code your list view is working fine but when click on list item just open your website and display particular item

    this is not way. i need display details view from rss feed. i think you just pass url of your site ?

    • James says:

      Hello,

      You can check the source code, the onItemClickListener. I pass two data to next activity:

      1. postInfo.putString(“content”, data.postContent);
      2. postInfo.putString(“link”, data.postLink);

      In the coming activity, PostViewActivity class, I provide two ways to show the content.
      1. show the content from rss
      2. show the content from the link

      By default, I commented the first option and just show the content from the link. If you like, you can do the visa versa

      Best Regards
      James

  18. Nabhoneel Majumdar says:

    Hi James! I have been trying to create this app for some time, but can’t quite get it right. I am new to Android and would be very glad if you helped me.

    After including RssDataController, how do I use it?
    How can I use it to get a PostData array and include it inside listView?

  19. Sachin says:

    How to update the modified List in Dummy List of Tutorial 1.

    • James says:

      First, you need to make sure the array type is :
      private PostData[] datas;

      Then, you can store PostData objects in the array. If you don’t know what’s PostData, please check tutorial 1.

  20. amna says:

    hy nice tutorial
    however i m not able to solve listData and postAdapter problem. it says that it cant resolver these symbols. please guide.
    thanks

  21. Abhishek says:

    I have created string variable postlink in class PostData.java but still im finding error 76,77 and 79 line for pdData.postlink. could you please help me with this.

    • James says:

      I guess there are something wrong in other place. Once you add postlink variable in class PostData.java, the pdData.postlink will not have any problems.

  22. Abhishek says:

    Should all the above codes be included in MainActivity.java…?

  23. Mohammed says:

    I am having error with the code on line 003

    private RSSXMLTag currentTag;

    could you please help me with this pls?

  24. rewdon says:

    you said xml parser is subclass of asynctask. where exactly i need to put the code?

  25. Mohamed says:

    Hello James ,
    i have followed your tutorial it’s very useful but i’m facing a problem now

    postDataList is always empty i tried to debug the code and i find out that this the block inside this ” else if (eventType == XmlPullParser.END_TAG)” doesn’t compile as the condition doesn’t match , so postDataList is always empty , any thoughts how can i make this works ?

    • James Liu says:

      First, please check your xml. If the condition “eventType == XmlPullParser.END_TAG” is never triggered, that means your xml structure is broken.

  26. Moiz says:

    James, my whole code crashes on the statement, connection.connect() statement. Kindly give a solution for this.

  27. hakan says:

    What is the

    import com.jms.rssreader.vo.PostData;
    import com.jms.rssreader.R;

    librarry. I dont understand.

    Please help

  28. Judy says:

    Hi James!

    Great tutorial! Thanks a lot for this. However, I’m having some problem with this line:

    postAdapter.notifyDataSetChanged();

    I get the following error: “postAdapter cannot be resolved”

    I looked through the code to look for postAdapter but all I could find was itemAdapter. When I replaced postAdapter with itemAdapter, I still get the same error. How can I fix this error?

    Thanks in advance!

    • James Liu says:

      postAdaper is the main class variable. In tutorial 1, I create it as an local variable. But in the tutorial, I have to declare it as an main class variable so that onPostExecute can access it.

      The same as listData, you have to change your listData type to ArrayList listData;

      Thanks

  29. ranaz says:

    Hi James, where do i put the link for the RSS Feed?

  30. Darrr says:

    Your code is very very stupid. You can’t use such thing to parse XML from URL. because you need retrieve whole XML.

    connection.setReadTimeout(10 * 1000);
    connection.setConnectTimeout(10 * 1000);

  31. Red says:

    this tutorial was great until this code here.

    I have gone through all the codes in the comment section and I still get this error.

    Error:(25, 13) error: cannot find symbol class RSSXMLTag.
    How can I fix it?

    • James Liu says:

      Hello,

      RSSXMLTag is a enum type available. Check this:

      private enum RSSXMLTag {
      TITLE, DATE, LINK, CONTENT, GUID, IGNORETAG;
      }

  32. namrata says:

    error occurring in Ignoretag

  33. namrata says:

    And for each and every line of code showing error as to be surrounded with try and catch

Leave a Reply

Weboy

Weboy