Android学习笔记_7_使用 sax 或者 dom 或者 pull 解析XML文件
一、Pull解析介绍:
Android上使用SAX和DOM方式解析XML的方法,并且对两种做了简单的比较,通过比较我们知道对在往往内存比较稀缺的移动设备上运行的Android系统来说,SAX是一种比较合适的XML解析方式。但是SAX方式的特点是需要解析完整个文档才会返回,如果在一个XML文档中我们只需要前面一部分数据,但是使用SAX方式还是会对整个文档进行解析,尽管XML文档中后面的大部分数据我们其实都不需要解析,因此这样实际上就浪费了处理资源。
Pull解析器和SAX解析器虽有区别但也有相似性。他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。而他们的相似性在运行方式上,Pull解析器也提供了类似SAX的事件(开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等),但需要调用next() 方法提取它们(主动提取事件)。
Android系统中和Pull方式相关的包为org.xmlpull.v1,在这个包中提供了Pull解析器的工厂类XmlPullParserFactory和Pull解析器XmlPullParser,XmlPullParserFactory实例调用newPullParser方法创建XmlPullParser解析器实例,接着XmlPullParser实例就可以调用getEventType()和next()等方法依次主动提取事件,并根据提取的事件类型进行相应的逻辑处理。
二、准备xml文件:
文件保存在src目录下
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="1001">
<name>张三</name>
<age>27</age>
</person>
<person id="1002">
<name>李四</name>
<age>25</age>
</person>
<person id="1003">
<name>王五</name>
<age>28</age>
</person>
<person id="1004">
<name>赵六</name>
<age>30</age>
</person>
</persons>
三、通过Pull解析和保存实现:
package com.example.service;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
import com.example.entity.Person; public class XMLParse {
/**
* 解析xml
* @param in 输入流
* @return
*/
public List<Person> parse(InputStream in) {
List<Person> persons=null;
Person person=null;
try {
//创建XmlPullParser,有两种方式
//方式一:使用工厂类XmlPullParserFactory
// XmlPullParserFactory pullFactory = XmlPullParserFactory.newInstance();
// XmlPullParser xmlPullParser = pullFactory.newPullParser();
// //方式二:使用Android提供的实用工具类android.util.Xml
XmlPullParser xmlPullParser = Xml.newPullParser();
xmlPullParser.setInput(in, "UTF-8");
int event = xmlPullParser.getEventType();
boolean isDone = false;
//具体解析xml
while ((event != XmlPullParser.END_DOCUMENT)&&(isDone != true)) {
switch (event) {
case XmlPullParser.START_DOCUMENT:
persons = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if("person".equals(xmlPullParser.getName())){
person = new Person();
int id = Integer.valueOf(xmlPullParser.getAttributeValue(0));
person.setId(id);
}
if("name".equals(xmlPullParser.getName())){
person.setName(xmlPullParser.nextText());
}
if("age".equals(xmlPullParser.getName())){
person.setAge(Integer.valueOf(xmlPullParser.nextText()));
}
break;
case XmlPullParser.END_TAG:
if("person".equals(xmlPullParser.getName())){
persons.add(person);
person=null;
}
break;
}
//调用next()方法主动提取事件
event = xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
return persons;
} /**
* 将对象保存成xml文件
* @param out
* @param persons
*/
public void save(OutputStream out,List<Person> persons){
try {
XmlSerializer xml = Xml.newSerializer();
xml.setOutput(out, "UTF-8");
xml.startDocument("UTF-8", true);
xml.startTag(null, "persons");
for (Person person : persons) {
xml.startTag(null, "person");
//设置属性
xml.attribute(null, "id", person.getId().toString()); xml.startTag(null, "name");
xml.text(person.getName());//设置内容
xml.endTag(null, "name"); xml.startTag(null, "age");
xml.text(person.getAge().toString());
xml.endTag(null, "age"); xml.endTag(null, "person");
}
xml.endTag(null, "persons");
xml.endDocument();
out.flush();//防止是缓冲流
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
四、测试与结果:
package com.example.test; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import android.test.AndroidTestCase;
import android.util.Log; import com.example.entity.Person;
import com.example.service.XMLParse; public class XMLParseTest extends AndroidTestCase {
private static String TAG ="XMLParseTest";
public void testParse() {
XMLParse p = new XMLParse();
//Person.xml文件在src目录下
InputStream in = XMLParseTest.class.getClassLoader().getResourceAsStream("Person.xml");
List<Person> persons = p.parse(in);
for (Person person : persons) {
Log.i(TAG, person.toString());
}
}
public void testSave() {
try {
XMLParse p = new XMLParse();
List<Person> persons=new ArrayList<Person>();
persons.add(new Person(10001,"tom",25));
persons.add(new Person(10002,"lily",26));
persons.add(new Person(10003,"xiaoming",27));
//将文件保存在当前应用所在包的files文件夹下
FileOutputStream fos=new FileOutputStream(new File(getContext().getFilesDir(),"xiaoming.xml"));
p.save(fos, persons);
} catch (Exception e) {
e.printStackTrace();
} }
}
将对象生成xml文件及保存位置:
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<persons>
<person id="10001">
<name>tom</name>
<age>25</age>
</person>
<person id="10002">
<name>lily</name>
<age>26</age>
</person>
<person id="10003">
<name>xiaoming</name>
<age>27</age>
</person>
</persons>
结果(在LogCat中加入XMLParseTest标签):


二、SAX解析介绍:
在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并根据文档的内容产生事件。而事件处理器则是org.xml.sax包中的ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口,它们分别处理事件源在解析XML文档过程中产生的不同种类的事件。在开发中没有必要直接从这4个接口直接继承,因为org.xml.sax.helper包提供了类DefaultHandler,其继承了这4个接口,在实际开发中直接从DefaultHandler继承并实现相关函数就可以了。
1、实体类和需要解析的xml配置文件:
public class Person {
private String id;
private String name;
private String age;
private String address;
}
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<id>1001</id>
<name>小王</name>
<age>信息学院</age>
<address>6258113</address>
</person>
<person>
<id>1002</id>
<name>小李</name>
<age>信息学院</age>
<address>12312</address>
</person>
</persons>
2、解析
package cn.sax.test; import java.io.InputStream;
import java.util.ArrayList; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; public class SAXXmlService extends DefaultHandler {
// //定义一个Person引用
Person person = null;
// 此处将XML里的数据封装成Person类,personList用于装解析后的数据
ArrayList<Person> personArr = null;
// 定义一个标记变量,标记当前的XML文件被解析到哪个标签
private String currentTag = null; /*
* 执行解析
*/
public static ArrayList<Person> getPersonInfos(InputStream stream)
throws Exception {
// 得到SAX解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
// 创建解析器
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
// 得到输入流
InputSource is = new InputSource(stream);
// 得到SAX解析实现类
SAXXmlService handler = new SAXXmlService();
xmlreader.setContentHandler(handler);
// 开始解析
xmlreader.parse(is);
return handler.personArr;
} @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
// 判断当前标签是否有效
if (currentTag != null) {
// //读取标签里面的内容
String value = new String(ch, start, length);
System.out.println("value"+value);
// 如果是Id标签,则读取Id标签的内容设置到Person的ID值上
if ("id".equalsIgnoreCase(currentTag)) {
person.setId(value);
} else if ("name".equalsIgnoreCase(currentTag)) {// name标签
person.setName(value);
} else if ("age".equalsIgnoreCase(currentTag)) {
// age标签
person.setAge(value);
} else if ("address".equalsIgnoreCase(currentTag)) {
// address标签
person.setAddress(value);
}
}
} /* 解析XML时,当开始读取XML文档时 */
@Override
public void startDocument() throws SAXException {
personArr = new ArrayList<Person>();
} @Override
public void endDocument() throws SAXException {
super.endDocument();
} /* 解析XML时,当开始读到一个元素标签开始时 */
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals("person")) {
person = new Person();
}
currentTag = qName;
} /* 解析XML时,当读到结束一个元素标签时 */
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 将当前标签名置空
currentTag = null;
// 如果当前结束的标签名是person的话,代表一个person对象已经读取完毕。将其添加到list后置空
if (qName.equals("person")) {
personArr.add(person);
person = null;
}
} }
3、测试
public class Test {
public static void main(String[] args) {
InputStream stream;
try {
File file = new File("src/NewFile.xml");
stream = new FileInputStream(file);
List<Person> persons = SAXXmlService.getPersonInfos(stream);
for (Person person : persons) {
System.out.println(person);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Android学习笔记_7_使用 sax 或者 dom 或者 pull 解析XML文件的更多相关文章
- Android SAX、DOM、Pull解析xml文件剖析与案例讲解
XML介绍 XML(Extensible Markup Language) 即可扩展标记语言,与HTML一样,都是SGML(Standard Generalized Markup Language,标 ...
- Java sax、dom、pull解析xml
-------------------------------------SAX解析xml---------------------------------- >Sax定义 SAX是一个解析速度 ...
- Dom方法,解析XML文件
Dom方法,解析XML文件的基本操作 package com.demo.xml.jaxp; import java.io.IOException; import javax.xml.parsers.D ...
- python XML文件解析:用xml.dom.minidom来解析xml文件
python解析XML常见的有三种方法: 一是xml.dom.*模块,是W3C DOM API的实现,若需要处理DOM API则该模块很合适, 二是xml.sax.*模块,它是SAX API的实现,这 ...
- [android] 采用pull解析xml文件
/***********2016年5月6日 更新**********************/ 知乎:Android 中有哪几种解析 xml 的类,官方推荐哪种 ? 以及它们的原理和区别? 刘吉财: ...
- Android中pull解析XML文件的简单使用
首先,android中解析XML文件有三种方式,dom,sax,pull 这里先讲pull,稍候会说SAX和DOM pull是一种事件驱动的xml解析方式,不需要解析整个文档,返回的值是数值型,是推荐 ...
- Android pull解析xml文件
本文介绍android中使用pull来解析xml文件 先自己写一个xml文件,存一些天气信息 <?xml version="1.0" encoding="UTF-8 ...
- android——使用pull解析xml文件
1.persons.xml 将persons.xml文件放到src目录下.其代码如下: <?xml version='1.0' encoding='UTF-8' standalone='yes' ...
- android 生成、pull解析xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...
随机推荐
- bzoj 5329: [Sdoi2018]战略游戏
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- [转]Newtonsoft.Json高级用法
本文转自:http://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多 ...
- glyphicons-halflings-regular.woff2 文件 404
搜索了下,果然是因为mine没有配置的原因. http://stackoverflow.com/questions/32300578/how-to-remove-error-about-glyphic ...
- spring boot 2.0.0 + mybatis 报:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
spring boot 2.0.0 + mybatis 报:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required 无法启动 ...
- html相对定位绝对定位
孔子说:“温故而知新,可以为师矣.”这几天参加了一个免费的前端课,每天晚上都有直播,讲解一个独立的案例.在听前端基础的时候,发现自己有不少东西没学会,平时在学校虽说html也写了不少,但有好大一部分都 ...
- js数组的sort排序的原理和应用
1.js sort()方法的应用: 首先:如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序.要实现这一点,首先应把数组的元素都转换成字符串( ...
- ezdpl Linux自动化部署实战
最近把ezdpl在生产环境中实施了,再加上这段时间的一些修改,一并介绍一下. 再次申明: ezdpl不是开箱即用的,需要根据自己的应用环境定制.对初学者来说使用起来反倒困难更多.风险更大. 它不是一个 ...
- Flask入门之模板导入与块宏(六)
1 模板包含include 主体结构(导入整个模板,直接渲染不可修改) {% include('模板名称') %} {% include('目录/模板名称') %} 功能: 其功能就是将另一个模板加载 ...
- 【Leetcode】【Easy】Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- dede如何调用一级栏目和子集栏目及其文章
{dede:channelartlist row=6} <a href='{dede:field name='typeurl'/}'>{dede:field name='typename' ...