Android: Parsing XML with children and attributes using DOM

22 November 2012 By Nithya Vasudevan 14,541 views 2 Comments
13 Flares Twitter 1 Facebook 2 Google+ 10 13 Flares ×

Project Description

  • In the previous Android example here we saw how to parse a simple XML using DOM parser.
  • This example shows how to parse a XML containing element attributes, multi level child nodes using Android DOM parser.

Environment Used

  • JDK 6 (Java SE 6)
  • Eclipse Indigo IDE for Java EE Developers (3.7.1)
  • Android SDK 4.0.3 / 4.1 Jelly Bean
  • Android Development Tools (ADT) Plugin for Eclipse (ADT version 20.0.0)
  • Refer this link to setup the Android development environment

Prerequisites

  • HelloWorld Example
  • Android: Simple XML DOM parser

Create Android Project

  • Create a new Android Project and name it as “DOMParserAttrChildNodes”.
  • Enter the package name as “com.theopentutorials.android”.
  • Enter the Activity name as “DOMParserActivity”.
  • Click Finish.

Create XML file

In the project’s assets folder, create a new XML file and name it as “employees.xml” and copy the following.

<?xml version="1.0" encoding="UTF-8"?>
<employees>
	<employee id = "2163">
	    <name>Kumar</name>
		<department>Development</department>
		<type>Permanent</type>		
		<email>[email protected]</email>
		<address>
	        <line1>1201 Main Rd</line1>
	        <city>Peoria</city>
	        <state>Illinois</state>
	        <zipcode>61606</zipcode>
   		</address>
	</employee>
	
	<employee id = "6743">
		<name>Ram</name>
		<department>DB</department>
		<type>Contract</type>		
		<email>[email protected]</email>
		<address>
	        <line1>163 Main Street</line1>
	        <city>Chennai</city>
	        <state>TN</state>
	        <zipcode>600001</zipcode>
   		</address>
	</employee>
	
	<employee id = "6763">
	    <name>Timmy</name>
		<department>Testing</department>
		<type>Permanent</type>		
		<email>[email protected]</email>
		<address>
	        <line1>2163 1st Avenue</line1>
	        <city>Chicago</city>
	        <state>Illinois</state>
	        <zipcode>60631</zipcode>
   		</address>
	</employee>
</employees>

strings.xml

Open res/values/string.xml and replace it with following content.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, DOMParserActivity!</string>
    <string name="app_name">DOMParserAttrChildNodes</string>
	<string name="button">Parse XML using DOM</string>
</resources>

XML layout files

This Android application uses two layout files; one for displaying the main layout containing ListView to display the result of DOM parser and another for defining the ListView item which contains a single TextView.
Open main.xml file in res/layout and copy the following content.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

 <Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/button" />
    
   <ListView
        android:id="@+id/employeeList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
       />
</LinearLayout>

Create a new layout file list_item.xml in res/layout and copy the following content.

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/title"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textColor="#CC0033"
    android:textSize="16sp" />

Create Bean classes

Address.java

Create a new Java class “Address.java” in package “com.theopentutorials.android.beans

package com.theopentutorials.android.beans;
public class Address {

	private String line;
	private String city;
	private String state;
	private long zipcode;

	public String getLine() {
		return line;
	}
	public void setLine(String line) {
		this.line = line;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	public long getZipcode() {
		return zipcode;
	}
	public void setZipcode(long zipcode) {
		this.zipcode = zipcode;
	}	
}

Employee.java

Create a new Java class “Employee.java” in package “com.theopentutorials.android.beans

package com.theopentutorials.android.beans;
public class Employee {
	private String name;
	private int id;
	private String department;
	private String type;
	private String email;
	private Address address;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getDepartment() {
		return department;
	}
	public void setDepartment(String department) {
		this.department = department;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	@Override
	public String toString() {
		return id + ": " + name + "\n" + department + "-" + type;
	}

	public String getDetails() {
		String result = id + ": " + name + "\n" + department + "-" + type
				+ "\n" + email + "\n" + "Address:\n" + address.getLine() + "\n"
				+ address.getCity() + ", " + address.getState() + " "
				+ address.getZipcode();
		return result;
	}

	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
}

Create XMLDOMParser class

package com.theopentutorials.android.xml;

import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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;
import android.util.Log;

public class XMLDOMParser {
	//Returns the entire XML document 
	public Document getDocument(InputStream inputStream) {
		Document document = null;
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = factory.newDocumentBuilder();
			InputSource inputSource = new InputSource(inputStream);
			document = db.parse(inputSource);
		} catch (ParserConfigurationException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (SAXException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (IOException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		}
		return document;
	}

	/*
	 * I take a XML element and the tag name, look for the tag and get
	 * the text content i.e for <employee><name>Kumar</name></employee>
	 * XML snippet if the Element points to employee node and tagName 
	 * is name I will return Kumar. Calls the private method 
	 * getTextNodeValue(node) which returns the text value, say in our 
	 * example Kumar. */
	public String getValue(Element item, String name) {
		NodeList nodes = item.getElementsByTagName(name);
		return this.getTextNodeValue(nodes.item(0));
	}

	private final String getTextNodeValue(Node node) {
		Node child;
		if (node != null) {
			if (node.hasChildNodes()) {
				child = node.getFirstChild();
				while(child != null) {
					if (child.getNodeType() == Node.TEXT_NODE) {
						return child.getNodeValue();
					}
					child = child.getNextSibling();
				}
			}
		}
		return "";
	}
}

Create DOMParserActivity class

package com.theopentutorials.android;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.theopentutorials.android.beans.Address;
import com.theopentutorials.android.beans.Employee;
import com.theopentutorials.android.xml.XMLDOMParser;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class DOMParserActivity extends Activity implements OnClickListener,
		OnItemClickListener {
	Button button;
	ListView listView;
	List<Employee> employees = null;

	// XML node names
	static final String ATTR_ID = "id";
	static final String NODE_EMP = "employee";
	static final String NODE_NAME = "name";
	static final String NODE_DEPT = "department";
	static final String NODE_TYPE = "type";
	static final String NODE_EMAIL = "email";
	static final String NODE_ADDR = "address";
	static final String NODE_LINE1 = "line1";
	static final String NODE_CITY = "city";
	static final String NODE_STATE = "state";
	static final String NODE_ZIP = "zipcode";

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		findViewsById();
		button.setOnClickListener(this);
	}

	private void findViewsById() {
		button = (Button) findViewById(R.id.button);
		listView = (ListView) findViewById(R.id.employeeList);
	}

	public void onClick(View view) {
		XMLDOMParser parser = new XMLDOMParser();
		AssetManager manager = getAssets();
		InputStream stream;
		try {
			stream = manager.open("employees.xml");
			Document doc = parser.getDocument(stream);

			// Get elements by name employee
			NodeList nodeList = doc.getElementsByTagName(NODE_EMP);
			employees = new ArrayList<Employee>();
			/*
			 * for each <employee> element get text of name, department, type
			 * and email and line1, city, state, zipcode of <address> element.
			 */
			for (int i = 0; i < nodeList.getLength(); i++) {
				Element e = (Element) nodeList.item(i);

				Employee employee = new Employee();

				employee.setId(Integer.parseInt(e.getAttribute(ATTR_ID)));
				employee.setName(parser.getValue(e, NODE_NAME));
				employee.setDepartment(parser.getValue(e, NODE_DEPT));
				employee.setType(parser.getValue(e, NODE_TYPE));
				employee.setEmail(parser.getValue(e, NODE_EMAIL));

				Address address = new Address();
				address.setLine(parser.getValue(e, NODE_LINE1));
				address.setCity(parser.getValue(e, NODE_CITY));
				address.setState(parser.getValue(e, NODE_STATE));
				address.setZipcode(Long.parseLong(parser.getValue(e, NODE_ZIP)));
				employee.setAddress(address);

				employees.add(employee);
			}
			displayOutput();

		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	private void displayOutput() {
		ArrayAdapter<Employee> adapter = new ArrayAdapter<Employee>(this,
				R.layout.list_item, employees);
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(this);
	}

	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		Employee employee = employees.get(position);
		Toast.makeText(parent.getContext(), employee.getDetails(),
				Toast.LENGTH_LONG).show();
	}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.theopentutorials.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name="com.theopentutorials.android.DOMParserActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>  

Output

Run your application

Project Folder Structure

The complete folder structure of this example is shown below.

Tags: , , , , , , , , , , , , , ,

  • Endar

    Can I use your tutorial for android with SDK 8?
    Thanks

  • manju

    Hi Nithya Vasudevan,

    very nice tutorial for beginners, I liked the way it was first explained for simple parset and followed with multi level nodes. This helped me a lot in building my own xml parser.

    Thanks a lot.

    -regards,
    Manju