由于三种解析方法都实现了一个功能,就是对xml文件进行解析,所以在这里我们可以将解析方法定义为一个接口,三种解析方法都实现这个接口。下面是实现的接口。
IXmlParseService:
package cn.yj3g.service;
import java.io.InputStream;
import java.util.List;
import cn.yj3g.entity.Person;
//定义一个接口
public interface IXmlParseService {
//接口中的一个解析方法。如果引用这个接口,就要实现这个方法,这样做更简便,封装性更好。
public List getPersonsByParseXml(InputStream is) throws Exception;
}
下来就是具体用三种方式对xml实现解析。下面是三种解析方式的具体代码:
<1>DOM解析 DomParseService:
package cn.yj3g.service;
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;
/**
* DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。Node对象提供了一系列常量来代表结点的类型
* ,当开发人员获得某个Node类型后,就可以把Node节点转换成相应节点对象(Node的子类对象),以便于调用其特有的方法。
* Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容.
*
* 缺点:
* 一次性的完全加载整个xml文件,需要消耗大量的内存。
*/
public class DomParseService implements IXmlParseService {
@Override
public List getPersonsByParseXml(InputStream is) throws Exception {
List list = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
// 得到根元素,这里是persons
Element root = document.getDocumentElement();
// 得到一个集合,里面存放在xml文件中所有的person
NodeList nodeList = root.getElementsByTagName("person");
//
if (nodeList == null || nodeList.getLength() == 0) {
return null;
}
// 初始化
list = new ArrayList();
for (int i = 0; i < nodeList.getLength(); i++) {
// xml中的person标签
Element element = (Element) nodeList.item(i);
Person p = new Person();
// 得到person的id属性
int id = Integer.parseInt(element.getAttribute("id"));
p.setId(id);
// 得到name
String name = getAttrText(element, "name");
p.setName(name);
// 得到age
String age = getAttrText(element, "age");
p.setAge(new Integer(age));
list.add(p);
}
return list;
}
/**
* 获得指定元素的子元素中的文本内容
*/
public String getAttrText(Element element, String name) {
NodeList nodeList2 = element.getChildNodes();
Node node = null;
for (int i = 0; i < nodeList2.getLength(); i++) {
node = nodeList2.item(i);
if (node.getNodeName().equals(name)) {
return node.getTextContent();
}
}
return null;
}
}
<2>SAX解析 SAXParseService:
package cn.yj3g.service;
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;
/**
* 优点:SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。
*
*/
public class SAXParseService implements IXmlParseService {
public List getPersonsByParseXml(InputStream is) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
saxHandler handler = new saxHandler();
//
parser.parse(is, handler);
return handler.getList();
}
// 自定义一个handler实现DefaultHandler并 重写它的相关方法
private class saxHandler extends DefaultHandler {
String currunt = null;
List list = null;
Person p = null;
@Override
public void startDocument() throws SAXException {
list = new ArrayList();
}
@Override
public void endDocument() throws SAXException {
}
// 开始解析元素
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if ("person".equals(localName)) {
p = new Person();
p.setId(Integer.parseInt(attributes.getValue("id")));
} else if ("name".equals(localName) || "age".equals(localName)) {
currunt = localName;
}
}
// 元素解析结束
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if ("person".equals(localName)) {
list.add(p);
} else if ("name".equals(localName) || "age".equals(localName)) {
currunt = null;
}
}
// 解析文本
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String s = new String(ch, start, length);
if ("name".equals(currunt)) {
p.setName(s);
} else if ("age".equals(currunt)) {
p.setAge(Integer.parseInt(s));
}
}
// 返回list
public List getList() {
return list;
}
}
}
<3>PULL解析 PullParseService:
package cn.yj3g.service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import cn.yj3g.entity.Person;
/**
* 优点:不是一次加载,中途可以停止。
*
*/
public class PullParseService implements IXmlParseService {
public List getPersonsByParseXml(InputStream is) throws Exception {
List list = null;
Person p = null;
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
//设置输入流
parser.setInput(is, "utf-8");
//parser的几种事件类型
int type = parser.getEventType();
while (type != XmlPullParser.END_DOCUMENT) {
//
String typename = parser.getName();
switch (type) {
//文档开始 -->xml中的persons
case XmlPullParser.START_DOCUMENT:
list = new ArrayList();
break;
//元素开始
case XmlPullParser.START_TAG:
if ("person".equals(typename)) {
p = new Person();
p.setId(Integer.parseInt(parser.getAttributeValue(0)));
//
} else if ("name".equals(typename)) {
p.setName(parser.nextText());
//
} else if ("age".equals(typename)) {
p.setAge(Integer.parseInt(parser.nextText()));
}
break;
//元素结束
case XmlPullParser.END_TAG:
if ("person".equals(typename)) {
list.add(p);
p=null;
break;
}
}
//最最重要的一步,pull解析中的特有的方法,解析下一个标签
type = parser.next();
}
return list;
}
}
下来就是在主界面上通过Button设置监听来调用三种解析方法对xml文件进行解析,并将解析出来的数据放在一个ListView中。
主界面:XMLParseActivity:
package cn.yj3g.XMLParseActivity;
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.view.View;
import android.view.View.OnClickListener;
import android.widget.SimpleAdapter;
import cn.yj3g.TL23_xml_test.R;
import cn.yj3g.entity.Person;
import cn.yj3g.service.DomParseService;
import cn.yj3g.service.PullParseService;
import cn.yj3g.service.SAXParseService;
public class XMLParseActivity extends ListActivity implements
OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 找到Button按钮并添加监听
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 list = null;
//
InputStream is = null;
AssetManager manager = getAssets();
try {
//找到解析的文件
is = manager.open("persons.xml");
switch (id) {
case R.id.btn_dom:
//调用DOM解析方法对文件进行解析
list = new DomParseService().getPersonsByParseXml(is);
break;
case R.id.btn_sax:
//调用SAX解析方法对文件进行解析
list = new SAXParseService().getPersonsByParseXml(is);
break;
case R.id.btn_pull:
//调用PULL解析方法对文件进行解析
list = new PullParseService().getPersonsByParseXml(is);
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
showUI(list);
}
//运用Adapter方法将所得到的List显示在ListView中
public void showUI(List list) {
List> data = new ArrayList>();
for (Person p : list) {
Map map = new HashMap();
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);
}
}
布局文件:
main.xml:
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:background="#222222">
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="DOM显示"
android:layout_weight="1.0"
android:layout_gravity="center"/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="SAX显示"
android:layout_weight="1.0"
android:layout_gravity="center"/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="PULL显示"
android:layout_weight="1.0"
android:layout_gravity="center"/>
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ID"
android:layout_weight="1.0"
android:layout_gravity="center"/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="姓名"
android:layout_weight="1.0"
android:layout_gravity="center"/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="年龄"
android:layout_weight="1.0"
android:layout_gravity="center"/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
person_list_item.xml:
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
这样我们这个项目就做好了,就可以实现解析xml的功能了。