Android: Parsing XML with children and attributes using DOM
Contents
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
Project Folder Structure
The complete folder structure of this example is shown below.
Tags: Android 4 Examples, Android 4 icecream sandwich examples, Android 4.1 Jelly Bean Examples, Android Activity, Android ArrayAdapter Example, Android AssetManager, Android assets folder, Android DOM Parser Example, Android Examples, Android LinearLayout, Android ListView, Android TextView, Android XML DOM parser, Android XML layout, Android XML parser example