詳解android解析Xml的三種方式——DOM、SAX以及XMLpull

今天學習了android解析Xml的三種方式——DOM、SAX以及XMLpull,這裏對它們進行總結。


如果理解有誤,歡迎指正 ^_*

一、DOM方式解析:

xml是先把xml文檔都讀到內存中,然後再用DOM API來訪問樹形結構,並獲取數據。這個寫起來很簡單,但是很消耗內存。要是數據過大,手機不夠牛逼,可能手機直接死機。

常用的DoM接口和類:

Document:該接口定義分析並創建DOM文檔的一系列方法,它是文檔樹的根,是操作DOM的基礎。
Element:該接口繼承Node接口,提供了獲取、修改XML元素名字和屬性的方法。
Node:該接口提供處理並獲取節點和子節點值的方法。
NodeList:提供獲得節點個數和當前節點的方法。這樣就可以迭代地訪問各個節點。
DOMParser:該類是Apache的Xerces中的DOM解析器類,可直接解析XML文件。

二、SAX解析技術:

SAX的工作原理簡單地說就是對文檔進行順序掃描,當掃描到文檔(document)開始與結束、元素(element)開始與結束、文檔(document)結束等地方時通知事件處理函數,由事件處理函數做相應動作,然後繼續同樣的掃描,直至文檔結束。

常用的接口和類:

Attrbutes:用於得到屬性的個數、名字和值。
DefaultHandler:它提供了這些接LI的缺省實現。在大多數情況下,爲應用程序擴展DefaultHandler並覆蓋相關的方法

三、XMLPull

XML pull提供了開始元素和結束元素。當某個元素開始時,我們可以調用parser.nextText0從XML文檔中提取所有字符數據。當解釋到一個文檔結束時,自動生成EndDocument
事件。

常用的接口和類:

XmlPullParser:XML pull解析器是一個在XMLPULL VlAP1中提供了定義解析功能的接口。
XmlSerializer:它是一個接口,定義了XML信息集的序列。
XmlPullParserFactory:這個類用於在XMPULL V1 API中創建XML Pull解析器。


以下是源碼:

寫了一個解析接口然後分別用三個類來實現。當然還可以寫成工具類的方式。

MainActivity:

  1. package cn.yj3g.TL23_xml_test;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.util.ArrayList;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import android.app.ListActivity;
  9. import android.content.res.AssetManager;
  10. import android.os.Bundle;
  11. import android.util.Log;
  12. import android.view.View;
  13. import android.view.View.OnClickListener;
  14. import android.widget.SimpleAdapter;
  15. import cn.yj3g.entity.Person;
  16. import cn.yj3g.service2.DomParseService;
  17. import cn.yj3g.service2.PullParseService;
  18. import cn.yj3g.service2.SAXParseService;
  19. public class TL23_xml_testActivity extends ListActivity implements
  20. OnClickListener
  21. {
  22. @Override
  23. public void onCreate(Bundle savedInstanceState)
  24. {
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.main);
  27. findViewById(R.id.btn_dom).setOnClickListener(this);
  28. findViewById(R.id.btn_sax).setOnClickListener(this);
  29. findViewById(R.id.btn_pull).setOnClickListener(this);
  30. }
  31. public void onClick(View v)
  32. {
  33. int id = v.getId();
  34. List<Person> list = null;
  35. InputStream is = null;
  36. AssetManager manager = getAssets();
  37. try
  38. {
  39. is = manager.open("persons.xml");
  40. } catch (IOException e)
  41. {
  42. e.printStackTrace();
  43. }
  44. switch (id)
  45. {
  46. case R.id.btn_dom:
  47. try
  48. {
  49. list = new DomParseService().getPersonsByParseXml(is);
  50. showUI(list);
  51. } catch (Exception e)
  52. {
  53. e.printStackTrace();
  54. }
  55. break;
  56. case R.id.btn_sax:
  57. try
  58. {
  59. list = new SAXParseService().getPersonsByParseXml(is);
  60. showUI(list);
  61. } catch (Exception e)
  62. {
  63. e.printStackTrace();
  64. }
  65. break;
  66. case R.id.btn_pull:
  67. try
  68. {
  69. Log.v("TAG", "btn_pull");
  70. list = new PullParseService().getPersonsByParseXml(is);
  71. showUI(list);
  72. Log.v("TAG", list.size() + "");
  73. } catch (Exception e)
  74. {
  75. e.printStackTrace();
  76. }
  77. break;
  78. default:
  79. break;
  80. }
  81. try
  82. {
  83. is.close();
  84. } catch (IOException e)
  85. {
  86. // TODO Auto-generated catch block
  87. e.printStackTrace();
  88. }
  89. }
  90. public void showUI(List<Person> list)
  91. {
  92. List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
  93. for (Person p : list)
  94. {
  95. Map<String, Object> map = new HashMap<String, Object>();
  96. map.put("id", p.getId());
  97. map.put("name", p.getName());
  98. map.put("age", p.getAge());
  99. data.add(map);
  100. }
  101. String[] from =
  102. { "id", "name", "age" };
  103. int[] to =
  104. { R.id.tv_id, R.id.tv_name, R.id.tv_age };
  105. SimpleAdapter adapter = new SimpleAdapter(this, data,
  106. R.layout.person_list_item, from, to);
  107. setListAdapter(adapter);
  108. }
  109. }
package cn.yj3g.TL23_xml_test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.SimpleAdapter;
import cn.yj3g.entity.Person;
import cn.yj3g.service2.DomParseService;
import cn.yj3g.service2.PullParseService;
import cn.yj3g.service2.SAXParseService;

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

		findViewById(R.id.btn_dom).setOnClickListener(this);
		findViewById(R.id.btn_sax).setOnClickListener(this);
		findViewById(R.id.btn_pull).setOnClickListener(this);
	}

	public void onClick(View v)
	{
		int id = v.getId();
		List<Person> list = null;
		InputStream is = null;
		AssetManager manager = getAssets();
		try
		{
			is = manager.open("persons.xml");
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		switch (id)
		{
		case R.id.btn_dom:
			try
			{
				list = new DomParseService().getPersonsByParseXml(is);
				showUI(list);
			} catch (Exception e)
			{
				e.printStackTrace();
			}
			break;
		case R.id.btn_sax:
			try
			{
				list = new SAXParseService().getPersonsByParseXml(is);
				showUI(list);
			} catch (Exception e)
			{
				e.printStackTrace();
			}
			break;
		case R.id.btn_pull:
			try
			{
				Log.v("TAG", "btn_pull");
				list = new PullParseService().getPersonsByParseXml(is);
				showUI(list);
				Log.v("TAG", list.size() + "");
			} catch (Exception e)
			{
				e.printStackTrace();
			}
			break;
		default:
			break;
		}
		try
		{

			is.close();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void showUI(List<Person> list)
	{
		List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
		for (Person p : list)
		{
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("id", p.getId());
			map.put("name", p.getName());
			map.put("age", p.getAge());
			data.add(map);
		}
		String[] from =
		{ "id", "name", "age" };
		int[] to =
		{ R.id.tv_id, R.id.tv_name, R.id.tv_age };
		SimpleAdapter adapter = new SimpleAdapter(this, data,
				R.layout.person_list_item, from, to);
		setListAdapter(adapter);
	}
}

接口:

  1. package cn.yj3g.service2;
  2. import java.io.InputStream;
  3. import java.util.List;
  4. import cn.yj3g.entity.Person;
  5. public interface IXmlParseService {
  6. public List<Person> getPersonsByParseXml(InputStream is) throws Exception;
  7. }
package cn.yj3g.service2;

import java.io.InputStream;
import java.util.List;

import cn.yj3g.entity.Person;

public interface IXmlParseService {

	public List<Person> getPersonsByParseXml(InputStream is) throws Exception;
}

DOM實現類:

  1. package cn.yj3g.service2;
  2. import java.io.InputStream;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import javax.xml.parsers.DocumentBuilder;
  6. import javax.xml.parsers.DocumentBuilderFactory;
  7. import org.w3c.dom.Document;
  8. import org.w3c.dom.Element;
  9. import org.w3c.dom.Node;
  10. import org.w3c.dom.NodeList;
  11. import cn.yj3g.entity.Person;
  12. public class DomParseService implements IXmlParseService
  13. {
  14. @Override
  15. public List<Person> getPersonsByParseXml(InputStream is) throws Exception
  16. {
  17. List<Person> list = null;
  18. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  19. DocumentBuilder builder = factory.newDocumentBuilder();
  20. Document document = builder.parse(is);
  21. Element rootElement = document.getDocumentElement();
  22. NodeList nodeList = rootElement.getElementsByTagName("person");// 得到person節點鏈表
  23. if (nodeList == null || nodeList.getLength() == 0)
  24. {
  25. return null;
  26. }
  27. list = new ArrayList<Person>();
  28. for (int i = 0; i < nodeList.getLength(); i++)
  29. {
  30. Person person = new Person();
  31. Element element = (Element) nodeList.item(i);
  32. // 得到根節點屬性:id
  33. int id = Integer.parseInt(element.getAttribute("id"));
  34. person.setId(id);
  35. // 得到孩子節點:name
  36. NodeList nameList = element.getElementsByTagName("name");
  37. Element nameElement = (Element) nameList.item(0);
  38. String name = nameElement.getTextContent();
  39. person.setName(name);
  40. // 得到年齡:age
  41. NodeList ageList = element.getElementsByTagName("age");
  42. Element ageElement = (Element) ageList.item(0);
  43. String age = ageElement.getTextContent();
  44. person.setAge(Integer.parseInt(age));
  45. list.add(person);
  46. }
  47. return list;
  48. }
  49. }
package cn.yj3g.service2;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cn.yj3g.entity.Person;

public class DomParseService implements IXmlParseService
{

	@Override
	public List<Person> getPersonsByParseXml(InputStream is) throws Exception
	{
		List<Person> list = null;
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse(is);
		Element rootElement = document.getDocumentElement();
		NodeList nodeList = rootElement.getElementsByTagName("person");// 得到person節點鏈表
		if (nodeList == null || nodeList.getLength() == 0)
		{
			return null;
		}
		list = new ArrayList<Person>();
		for (int i = 0; i < nodeList.getLength(); i++)
		{
			Person person = new Person();
			Element element = (Element) nodeList.item(i);

			// 得到根節點屬性:id
			int id = Integer.parseInt(element.getAttribute("id"));
			person.setId(id);

			// 得到孩子節點:name
			NodeList nameList = element.getElementsByTagName("name");
			Element nameElement = (Element) nameList.item(0);
			String name = nameElement.getTextContent();
			person.setName(name);

			// 得到年齡:age
			NodeList ageList = element.getElementsByTagName("age");
			Element ageElement = (Element) ageList.item(0);
			String age = ageElement.getTextContent();
			person.setAge(Integer.parseInt(age));

			list.add(person);

		}

		return list;
	}
}

SAX實現類:

  1. package cn.yj3g.service2;
  2. import java.io.InputStream;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import javax.xml.parsers.SAXParser;
  6. import javax.xml.parsers.SAXParserFactory;
  7. import org.xml.sax.Attributes;
  8. import org.xml.sax.SAXException;
  9. import org.xml.sax.helpers.DefaultHandler;
  10. import cn.yj3g.entity.Person;
  11. public class SAXParseService implements IXmlParseService
  12. {
  13. public List<Person> getPersonsByParseXml(InputStream is) throws Exception
  14. {
  15. SAXParserFactory factory = SAXParserFactory.newInstance();
  16. SAXParser parser = factory.newSAXParser();
  17. MyHandler handler = new MyHandler();
  18. parser.parse(is, handler);
  19. return handler.getList();
  20. }
  21. private class MyHandler extends DefaultHandler
  22. {
  23. private List<Person> list;
  24. private Person person;
  25. private String currentTag;
  26. private List<Person> getList()
  27. {
  28. return list;
  29. }
  30. @Override
  31. public void startDocument() throws SAXException
  32. {
  33. list = new ArrayList<Person>();
  34. }
  35. @Override
  36. public void endDocument() throws SAXException
  37. {
  38. super.endDocument();
  39. }
  40. @Override
  41. public void startElement(String uri, String localName, String qName,
  42. Attributes attributes) throws SAXException
  43. {
  44. if ("person".equals(qName))
  45. {
  46. person = new Person();
  47. person.setId(Integer.parseInt(attributes.getValue("id")));
  48. } else if ("name".equals(qName) || "age".equals(qName))
  49. {
  50. currentTag = qName;
  51. }
  52. }
  53. @Override
  54. public void characters(char[] ch, int start, int length)
  55. throws SAXException
  56. {
  57. super.characters(ch, start, length);
  58. String s = new String(ch, start, length);
  59. if ("name".equals(currentTag))
  60. {
  61. person.setName(s);
  62. } else if ("age".equals(currentTag))
  63. {
  64. person.setId(Integer.parseInt(s));
  65. }
  66. currentTag = null;
  67. }
  68. @Override
  69. public void endElement(String uri, String localName, String qName)
  70. {
  71. if ("person".equals(qName))
  72. {
  73. list.add(person);
  74. person = null;
  75. }
  76. }
  77. }
  78. }
package cn.yj3g.service2;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import cn.yj3g.entity.Person;

public class SAXParseService implements IXmlParseService
{

	public List<Person> getPersonsByParseXml(InputStream is) throws Exception
	{
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = factory.newSAXParser();
		MyHandler handler = new MyHandler();
		parser.parse(is, handler);
		return handler.getList();
	}

	private class MyHandler extends DefaultHandler
	{
		private List<Person> list;
		private Person person;
		private String currentTag;

		private List<Person> getList()
		{
			return list;
		}

		@Override
		public void startDocument() throws SAXException
		{
			list = new ArrayList<Person>();
		}

		@Override
		public void endDocument() throws SAXException
		{
			super.endDocument();
		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException
		{
			if ("person".equals(qName))
			{
				person = new Person();
				person.setId(Integer.parseInt(attributes.getValue("id")));
			} else if ("name".equals(qName) || "age".equals(qName))
			{
				currentTag = qName;
			}
		}

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException
		{
			super.characters(ch, start, length);
			String s = new String(ch, start, length);
			if ("name".equals(currentTag))
			{
				person.setName(s);
			} else if ("age".equals(currentTag))
			{
				person.setId(Integer.parseInt(s));
			}
			currentTag = null;
		}

		@Override
		public void endElement(String uri, String localName, String qName)
		{
			if ("person".equals(qName))
			{
				list.add(person);
				person = null;
			}

		}

	}

}

Pull實現類:


  1. package cn.yj3g.service2;
  2. import java.io.InputStream;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import org.xmlpull.v1.XmlPullParser;
  6. import org.xmlpull.v1.XmlPullParserFactory;
  7. import android.util.Log;
  8. import cn.yj3g.entity.Person;
  9. public class PullParseService implements IXmlParseService
  10. {
  11. public List<Person> getPersonsByParseXml(InputStream is) throws Exception
  12. {
  13. List<Person> list = null;
  14. Person person = null;
  15. String currentTag = null;
  16. XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
  17. XmlPullParser parser = factory.newPullParser();
  18. parser.setInput(is, "utf-8");
  19. int type = parser.getEventType();
  20. while (type != XmlPullParser.END_DOCUMENT)
  21. {
  22. String typeName = parser.getName();
  23. if (type == XmlPullParser.START_TAG)
  24. {
  25. Log.v("TAG", "typeName=" + typeName);
  26. if ("persons".equals(typeName))
  27. {
  28. list = new ArrayList<Person>();
  29. } else if ("person".equals(typeName))
  30. {
  31. person = new Person();
  32. int id = Integer.parseInt(parser.getAttributeValue(0));
  33. person.setId(id);
  34. } else if ("name".equals(typeName))
  35. {
  36. currentTag = "name";
  37. } else if ("age".equals(typeName))
  38. {
  39. currentTag = "age";
  40. }
  41. } else if (type == XmlPullParser.END_TAG)
  42. {
  43. if ("person".equals(typeName))
  44. {
  45. list.add(person);
  46. person = null;
  47. }
  48. } else if (type == XmlPullParser.TEXT)
  49. {
  50. String s = parser.getText();
  51. if ("name".equals(currentTag))
  52. {
  53. person.setName(s);
  54. currentTag = null;
  55. } else if ("age".equals(currentTag))
  56. {
  57. person.setAge(Integer.parseInt(s));
  58. currentTag = null;
  59. }
  60. }
  61. type = parser.next();
  62. }
  63. Log.v("TAG", "size=" + list.size());
  64. return list;
  65. }
  66. }
package cn.yj3g.service2;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;
import cn.yj3g.entity.Person;

public class PullParseService implements IXmlParseService
{

	public List<Person> getPersonsByParseXml(InputStream is) throws Exception
	{

		List<Person> list = null;
		Person person = null;
		String currentTag = null;

		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
		XmlPullParser parser = factory.newPullParser();
		parser.setInput(is, "utf-8");
		int type = parser.getEventType();
		while (type != XmlPullParser.END_DOCUMENT)
		{
			String typeName = parser.getName();
			if (type == XmlPullParser.START_TAG)
			{
				Log.v("TAG", "typeName=" + typeName);
				if ("persons".equals(typeName))
				{
					list = new ArrayList<Person>();
				} else if ("person".equals(typeName))
				{
					person = new Person();
					int id = Integer.parseInt(parser.getAttributeValue(0));
					person.setId(id);
				} else if ("name".equals(typeName))
				{
					currentTag = "name";
				} else if ("age".equals(typeName))
				{
					currentTag = "age";
				}
			} else if (type == XmlPullParser.END_TAG)
			{
				if ("person".equals(typeName))
				{
					list.add(person);
					person = null;
				}
			} else if (type == XmlPullParser.TEXT)
			{
				String s = parser.getText();
				if ("name".equals(currentTag))
				{
					person.setName(s);
					currentTag = null;
				} else if ("age".equals(currentTag))
				{
					person.setAge(Integer.parseInt(s));
					currentTag = null;
				}
			}
			type = parser.next();
		}
		Log.v("TAG", "size=" + list.size());
		return list;
	}
}



Person測試類:

  1. package cn.yj3g.entity;
  2. public class Person {
  3. private int id;
  4. private String name;
  5. private int age;
  6. public Person(int id, String name, int age) {
  7. super();
  8. this.id = id;
  9. this.name = name;
  10. this.age = age;
  11. }
  12. public Person() {
  13. super();
  14. }
  15. public int getId() {
  16. return id;
  17. }
  18. public void setId(int id) {
  19. this.id = id;
  20. }
  21. public String getName() {
  22. return name;
  23. }
  24. public void setName(String name) {
  25. this.name = name;
  26. }
  27. public int getAge() {
  28. return age;
  29. }
  30. public void setAge(int age) {
  31. this.age = age;
  32. }
  33. @Override
  34. public String toString() {
  35. return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
  36. }
  37. }
package cn.yj3g.entity;

public class Person {

	private int id;
	private String name;
	private int age;

	public Person(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public Person() {
		super();
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}
要讀取的Person XML文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <persons>
  3. <person id="1">
  4. <name>劉備</name>
  5. <age>12</age>
  6. </person>
  7. <person id="2">
  8. <name>關羽</name>
  9. <age>14</age>
  10. </person>
  11. <person id="3">
  12. <name>張飛</name>
  13. <age>15</age>
  14. </person>
  15. </persons>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章