一、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文件的更多相关文章

  1. Android SAX、DOM、Pull解析xml文件剖析与案例讲解

    XML介绍 XML(Extensible Markup Language) 即可扩展标记语言,与HTML一样,都是SGML(Standard Generalized Markup Language,标 ...

  2. Java sax、dom、pull解析xml

    -------------------------------------SAX解析xml---------------------------------- >Sax定义 SAX是一个解析速度 ...

  3. Dom方法,解析XML文件

    Dom方法,解析XML文件的基本操作 package com.demo.xml.jaxp; import java.io.IOException; import javax.xml.parsers.D ...

  4. python XML文件解析:用xml.dom.minidom来解析xml文件

    python解析XML常见的有三种方法: 一是xml.dom.*模块,是W3C DOM API的实现,若需要处理DOM API则该模块很合适, 二是xml.sax.*模块,它是SAX API的实现,这 ...

  5. [android] 采用pull解析xml文件

    /***********2016年5月6日 更新**********************/ 知乎:Android 中有哪几种解析 xml 的类,官方推荐哪种 ? 以及它们的原理和区别? 刘吉财: ...

  6. Android中pull解析XML文件的简单使用

    首先,android中解析XML文件有三种方式,dom,sax,pull 这里先讲pull,稍候会说SAX和DOM pull是一种事件驱动的xml解析方式,不需要解析整个文档,返回的值是数值型,是推荐 ...

  7. Android pull解析xml文件

    本文介绍android中使用pull来解析xml文件 先自己写一个xml文件,存一些天气信息 <?xml version="1.0" encoding="UTF-8 ...

  8. android——使用pull解析xml文件

    1.persons.xml 将persons.xml文件放到src目录下.其代码如下: <?xml version='1.0' encoding='UTF-8' standalone='yes' ...

  9. android 生成、pull解析xml文件

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...

随机推荐

  1. [html/js]点击标题出现下拉列表

    效果 初始 点击后 参考代码 <!DOCTYPE html> <html> <head> <title>Layer group example</ ...

  2. 【Linux】Linux系统启动过程

    1.Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立终端 . 用户登录系统. 1.Linux系统的启动过程并不是大家想象 ...

  3. 6、Angular Route 路由

    1.没有嵌套路由 类似 ui-route 上述的html用红字标记的是必须导入的.这是因为:路由并不在ng2中,需要我们额外引入,另外我们需要设置base href,这是个什么东西呢?相当于我们后续所 ...

  4. Excle 导入DataSet

    using System.Data.OleDb;using System.Data; public void ReadExcelFiless()        {            //strin ...

  5. Git读档

    $ git config --global user.name "meng kai" $ git config --global user.email 363255751@qq.c ...

  6. Android使用Gradle命令动态传参完成打包,不需要修改代码

    不得不说,Gradle很强大,有人会问Gradle是什么?这里也不细讲,在我认为他就是一个构建神器.Gradle 提供了: 一个像 Ant 一样的非常灵活的通用构建工具 一种可切换的, 像 Maven ...

  7. dispatchTouchEvent,onTouchEvent与onInterceptTouchEvent

    1.首先明白一个常识:View 没有onInterceptTouchEvent事件,而ViewGroup这三个事件都有,是viewgroup继承View之后才加了一个方法叫onIntercepTouc ...

  8. selendroid之toast处理

    最近发现原来处理toast的操作失效了.仔细看了下原来的API.决定用switchTo来解决.driver.switchTo().defaultContent().findElement(By.id( ...

  9. python在Android下的自动化测试用法

    # This Python file uses the following encoding: utf-8from com.android.monkeyrunner import MonkeyRunn ...

  10. 三大集合框架之Set

    Set介绍 Set相对于List.Map是最简单的一种集合.集合中的对象不按特定的方式排序,并且没有重复对象. 特点: 它不允许出现重复元素: 不保证和政集合中元素的顺序 允许包含值为null的元素, ...