一、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. 【问题记录】 Linux 安装 apache 遇到的一些问题

    以下为linux上安装apache时自己遇到的一些问题,记录在这,以后遇到时也会不定时更新... 一.安装Apache提示APR not found的解决办法 解决方法: 1. 网站 http://a ...

  2. zookeeper 常用命令

    服务管理 启动ZK服务: zkServer.sh start 查看ZK状态: zkServer.sh status 停止ZK服务: zkServer.sh stop 重启ZK服务: zkServer. ...

  3. C# 获取电脑硬盘剩余空间

    获取本地硬盘的所有剩余空间: 主要应用到System.IO类库的:Driveinfo.Directory,将model转换成json需要用到Newtonsoft.Json.JsonConvert.Se ...

  4. 关于FileFOutputStream应用中的FileNotFoundException问题

    在使用fileoutputstream时经常出现FileNotFoundException问题,即便是同一个程序(可行)改了一下包名再重新编译,就会无缘无故的抛出FileNotFoundExcepti ...

  5. LI居中

    在用UL-LI时,有适合需要将Li里面的内容居中显示:方法有两种:(推荐)1.设置LI的display为inline(规定应该从父元素继承 display 属性的值),为LI设置长度,设置text-a ...

  6. Canvas知识点汇总

    本文主要记录Canvas基础知识汇总. 1.Canvas定义 <canvas> 元素是HTML5中的新元素,通过它可以在网页中绘制出所需的图形.<canvas>标签只是图形的容 ...

  7. asp.net学习视频大全(共800集)

    今天在网上找asp.net学习视频时,发现了一些好的学习资源,记录一下供大家学习. 资料名称 下载地址 <ASP.NET4.0从入门到精通>随书教学视频  http://down.51ct ...

  8. Java开发中代码规范有哪些?

    Java开发中所要遵守的编码规范大体上有如下7点.命名规范.注释规范.缩进排版规范.文件名规范.声明规范.语句规范以及编程规范. 1.命名规范 (1)所有的标示符都只能用ASCⅡ字母(A-Z或a-z) ...

  9. JSTL格式化标签库

    导入标签库需要使用taglib指令! <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/forma ...

  10. SharePoint2010 HTTP Error 503. The service is unavailable 解决方法

    1.更改系统管理员用户密码前提 因为更改系管理员用户密码会影响到 "SharePoint2010"正常运行,所在尽量不要更改系统管理员用户的密码, 必须更改密码的话,需要注意以两点 ...