今天学习了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:
- 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);
- }
- }
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);
}
}
接口:
- 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;
- }
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实现类:
- 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;
- }
- }
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实现类:
- 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;
- }
- }
- }
- }
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实现类:
- 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;
- }
- }
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;
}
}
- 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 + "]";
- }
- }
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文件:
- <?xml version="1.0" encoding="utf-8"?>
- <persons>
- <person id="1">
- <name>刘备</name>
- <age>12</age>
- </person>
- <person id="2">
- <name>关羽</name>
- <age>14</age>
- </person>
- <person id="3">
- <name>张飞</name>
- <age>15</age>
- </person>
- </persons>