Parsing an XML from Online in Android

In the previous example I showed how to parse an xml that is stored in a file in res/xml folder.
In this post I will show you how to parse an xml that is stored in a server in an xml file.

Here I am using an xml that is stored in here

Here is the java code for that.

First create a fresh project and name it ParseXMLDemo

Then in the ParseXMLDemo.java file copy this code

package com.coderzheaven.pack;

import java.util.ArrayList;
import java.util.HashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class ParseXMLDemo extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

        String xml = ParseXMLMethods.getXML();
        Document doc = ParseXMLMethods.XMLfromString(xml);

        int numResults = ParseXMLMethods.numResults(doc);

        if((numResults <= 0)){
        	Toast.makeText(ParseXMLDemo.this, "There is no data in the xml file", Toast.LENGTH_LONG).show();
        	finish();
        }

		NodeList children = doc.getElementsByTagName("os");

		for (int i = 0; i < children.getLength(); i++) {
			HashMap<String, String> map = new HashMap<String, String>();
			Element e = (Element)children.item(i);
			map.put("id", ParseXMLMethods.getValue(e, "id"));
        	map.put("name", ParseXMLMethods.getValue(e, "name"));
        	map.put("site", ParseXMLMethods.getValue(e, "site"));
        	mylist.add(map);
		}

        ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.list_layout,
                        new String[] { "name", "site" },
                        new int[] { R.id.title, R.id.subtitle});

        setListAdapter(adapter);

        final ListView lv = getListView();
        lv.setOnItemClickListener(new OnItemClickListener() {
        	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        		@SuppressWarnings("unchecked")
				HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);
        		Toast.makeText(ParseXMLDemo.this,o.get("name"), Toast.LENGTH_LONG).show();
			}
		});
    }
}

Now create another java file inside the src folder and name it ParseXMLMethods.java and copy this contents into it.

package com.coderzheaven.pack;

import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class ParseXMLMethods {

	public final static Document XMLfromString(String xml){

		Document doc = null;

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
	        is.setCharacterStream(new StringReader(xml));
	        doc = db.parse(is);

		} catch (ParserConfigurationException e) {
			System.out.println("XML parse error: " + e.getMessage());
			return null;
		} catch (SAXException e) {
			System.out.println("Wrong XML file structure: " + e.getMessage());
            return null;
		} catch (IOException e) {
			System.out.println("I/O exeption: " + e.getMessage());
			return null;
		}
        return doc;
	}

	 public final static String getElementValue( Node elem ) {
	     Node kid;
	     if( elem != null){
	         if (elem.hasChildNodes()){
	             for( kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling() ){
	                 if( kid.getNodeType() == Node.TEXT_NODE  ){
	                     return kid.getNodeValue();
	                 }
	             }
	         }
	     }
	     return "";
	 }

	 public static String getXML(){
			String line = null;

			try {

				DefaultHttpClient httpClient = new DefaultHttpClient();
				HttpPost httpPost = new HttpPost("http://coderzheaven.com/xml/test.xml");

				HttpResponse httpResponse = httpClient.execute(httpPost);
				HttpEntity httpEntity = httpResponse.getEntity();
				line = EntityUtils.toString(httpEntity);

			} catch (Exception e) {
				line = "Internet Connection Error >> " + e.getMessage();
			}
			return line;
	}

	public static int numResults(Document doc){
		Node results = doc.getDocumentElement();
		int res = -1;
		try{
			res = Integer.valueOf(results.getAttributes().getNamedItem("count").getNodeValue());
		}catch(Exception e ){
			res = -1;
		}
		return res;
	}

	public static String getValue(Element item, String str) {
		NodeList n = item.getElementsByTagName(str);
		return ParseXMLMethods.getElementValue(n.item(0));
	}
}

Now the main layout file main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ListView
	 	android:id="@id/android:list"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:layout_weight="1"
	    android:background="#FF0000"
	 	android:drawSelectorOnTop="false" />
</LinearLayout>

Create another file named list_layout.xml inside the layout folder and copy this code into it.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="7dp"
    >
<TextView
	android:id="@+id/title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:padding="2dp"
    android:textSize="20dp"
    android:textStyle="bold"
    />
    <TextView
	android:id="@+id/subtitle"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="2dp"
    android:textSize="14dp"
    android:textColor="#000000" />
</LinearLayout>

This is the Strings.xml file

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, ParseXMLDemo!</string>
    <string name="app_name">ParseXMLDemo Coderzheaven.com</string>
</resources>

Now you are done go on and run the application.

Parse XML in Android

Parse XML in Android

Get the full source code from here and don’t forget to comment on this post.

29 thoughts on “Parsing an XML from Online in Android

  1. yogo

    works perfectly, but I have problems with some characters such as: í, ó, “, and others I could not know how to fix.

    any suggestions for viewing these characters well.

    Reply
    1. mehmet

      HttpResponse httpResponse = httpClient.execute(httpPost);
      HttpEntity httpEntity = httpResponse.getEntity();

      line = EntityUtils.toString(httpEntity, “UTF-8″);
      (ParseXMLMethods.java)

      Reply
  2. Kennedy

    Works well but i get a toast message that “There is no data in XML file.” I’ve even recreated the file and saved it on my localhost. what am suposed to do for the data to be displyed?

    Thanks!

    Reply
  3. Jin

    Code compiled easily. However whenever I try to run the code I get “There is no data in XML file”.
    I noticed that when the app gets to the getXml() method it catches the exception “Internet connection error” instead of returning the xml in string form.

    Is there something I’m missing? I’m using an android 2.3.3 AVD

    Reply
        1. James Post author

          Thanks Jim for pointing out that mistake. Actually I forgot to copy that when I changed my server.

          Reply
  4. Bram van Gemert

    Hi there,
    I followed your tutorial but when i try to run the application it crashes right away.
    And it gives a nullpointer exception.
    I didnt change the code or anything just copy pasted it…

    FYI its a android 2.3.3 project

    Reply
    1. James Post author

      Check the Logcat and find the line where are you getting the NullPointer exception. Paste that line here. I will check it.

      Reply
  5. Bram van Gemert

    its gives the error over here:

    int numResults = ParseXMLMethods.numResults(doc);

    if((numResults <= 0)){
    Toast.makeText(ParseXMLDemo.this, "There is no data in the xml file", Toast.LENGTH_LONG).show();
    finish();
    }

    when it checks iF numResults is equal or lower then 0. it crashes with a nullpointer. So i guess the numResults var isnt created the way it should. So its never really available

    Reply
    1. Bram van Gemert

      I’ve tried to fix this for over an hour now but it doesnt matter what i try it just wont work. Even when i give int numResults a fixed value of 2. its keeps crashing. How is this possible?

      Reply
      1. James Post author

        Did you tried downloading the complete source code of the post I provided below the post.

        Reply
        1. Bram van Gemert

          Yeah I tried that but it only works in that project. Even when i try to copy the classes and the layout files it. It gives a nullpointer.

          Reply
          1. James Post author

            OK then it’s your problem. You missed something, may be the permissions in the Manifest file.
            Recheck the project.

  6. Bram van Gemert

    I Checked every piece of the project but couldnt find it. Will check tomorrow morning again. But one quick question. If I use this code in an android 2.3.3 project then it should run fine right? its not like they changed the implementation of some lines of code?

    Reply
  7. Marko

    hello world :) i have one problem, using this code i create an application which reads RSS from one webpage, but in that RSS i have tag and with this url tag i must to switch to a new RSS. can you please help me..i know i must create a new for loop for this but it doesnt works. This is my code, sorry for my bad english..:)

    ArrayList<HashMap> mylist = new ArrayList<HashMap>();

    String xml = ParseXMLMethods.getXML(“http://www.sapunice.net/xmlapp/serije.php”);
    Document doc = ParseXMLMethods.XMLfromString(xml);

    //int numResults = ParseXMLMethods.numResults(doc);
    int numResults = 19;

    if((numResults <= 0)){
    Toast.makeText(ParseXMLDemoActivity.this, "There is no data in the xml file", Toast.LENGTH_LONG).show();
    finish();
    }

    NodeList children = doc.getElementsByTagName("item");

    for (int i = 0; i < numResults ; i++) {
    HashMap map = new HashMap();
    Element e = (Element)children.item(i);
    map.put(“img”, ParseXMLMethods.getValue(e, “img”));
    map.put(“title”, ParseXMLMethods.getValue(e, “title”));
    map.put(“url”, ParseXMLMethods.getValue(e, “url”));

    // parsiramo rss s detaljima

    ArrayList<HashMap> mylist1 = new ArrayList<HashMap>();

    String xmldetail = ParseXMLMethods.getXML(ParseXMLMethods.getValue(e, “url”));
    Document docdetail = ParseXMLMethods.XMLfromString(xmldetail);

    NodeList children_detail = docdetail.getElementsByTagName(“item”);

    for (int j = 0; j < children_detail.getLength(); j++) {
    HashMap map1 = new HashMap();
    Element ed = (Element)children.item(j);
    map1.put(“title”, ParseXMLMethods.getValue(ed, “title”));
    map1.put(“description”, ParseXMLMethods.getValue(ed, “description”));
    // map1.put(“description”, ParseXMLMethods.getValue(ed, “description”));

    mylist1.add(map1);

    ListAdapter adapter1 = new SimpleAdapter(this, mylist1 , R.layout.list_layout1,

    new String[] { “title”, “description”},
    new int[] { R.id.title1, R.id.subtitle1});

    setListAdapter(adapter1);

    final ListView lv1 = getListView();
    lv1.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View view, int position, long id) {

    //Intent addReport = new Intent(ParseXMLDemoActivity.this, ParseXMLDemoActivity.class);

    //startActivity(addReport);
    @SuppressWarnings(“unchecked”)
    HashMap v = (HashMap) lv1.getItemAtPosition(position);
    Toast.makeText(ParseXMLDemoActivity.this,v.get(“shortDesc”), Toast.LENGTH_LONG).show();

    }
    });
    }

    mylist1.add(map);

    }

    ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.list_layout,
    new String[] { “img”, “title”},
    new int[] { R.id.title, R.id.subtitle});

    setListAdapter(adapter);

    final ListView lv = getListView();
    lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View view, int position, long id) {

    Intent addReport = new Intent(ParseXMLDemoActivity.this, ParseXMLDemoActivity.class);

    startActivity(addReport);
    /*
    @SuppressWarnings(“unchecked”)
    HashMap o = (HashMap) lv.getItemAtPosition(position);
    Toast.makeText(ParseXMLDemoActivity.this,o.get(“description”), Toast.LENGTH_LONG).show();
    */

    Reply
  8. Pavel

    Hi, works great, until I’m trying to parse HTML text inside XML tags…

    My XML file has <![CDATA[TextMore text
    ]]>

    inside of it, alongside with simple Text tags.

    I couldn’t make the code to parse anything in between description tags.

    Would you kindly help?

    Reply
  9. Pingback: Parsing XML, NullPointerException with getDocumentElementCopyQuery CopyQuery | Question & Answer Tool for your Technical Queries,CopyQuery, ejjuit, query, copyquery, copyquery.com, android doubt, ios question, sql query, sqlite query, nodejsquery, dns

  10. Kai-Hong Chen

    This is part of my program
    and the end is always show me the message like “Internet Connection Error”
    is there any wrong point about connect to internet ? or other problem?

    try {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(“https://www.facebook.com/download/321063978060447/data.xml”);

    HttpResponse httpResponse = httpClient.execute(httpPost);
    HttpEntity httpEntity = httpResponse.getEntity();

    getdata = EntityUtils.toString(httpEntity,”UTF-8″);
    dom.ReadOnlineXML(getdata);

    } catch (Exception e) {
    getdata = “Internet Connection Error >> ” + e.getMessage();
    }

    Reply
    1. James Post author

      please check e.getMessage(); output. “Internet Connection Error >>” is the one you have writtem. there may be some other exception.
      Also check whether correct XML is coming from the URL you have provided.

      Reply
  11. foe

    Hello James,
    your class works very well with android:minSdkVersion=”8″ but not to android:minSdkVersion=”10″
    do you have an idea

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>