一、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. 解决 command not found: express

    需要先执行 sudo npm install -g express-generator 再安装 sudo npm install -g express 建立项目骨架 express -e   xxx

  2. 记一次MongoDB性能问题

    下面文章转载自火丁笔记,原作者描述了一次MongoDB数据迁移过程中遇到的性能问题及其解决方案,中间追查问题的方法和工具值得我们学习.下面是其原文: 最近忙着把一个项目从MySQL迁移到MongoDB ...

  3. bzoj 3243: [Noi2013]向量内积

    Description 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知 ...

  4. MySQL判断一个字段不包含中文

    中文=2个字节,英文或数字=1个字节,因此我们用mysql中两个函数比较字节和字符的长度是否相等来判断是否包含中文 select * from user where CHAR_LENGTH(name) ...

  5. node之log4js

    log4js的配置文件: "log4js": { "appenders": { "out": { "type": &qu ...

  6. Topcoder SRM 698 Div1 250 RepeatString(dp)

    题意 [题目链接]这怎么发链接啊..... Sol 枚举一个断点,然后类似于LIS一样dp一波 这个边界条件有点迷啊..fst了两遍... #include<bits/stdc++.h> ...

  7. 1729 单词查找树 2000年NOI全国竞赛

    1729 单词查找树 2000年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master         题目描述 Description 在进行文法分析的 ...

  8. 3、HTML属性

    属性的意义是为HTML提供附加信息. 属性中,名称和值总是成对出现.比如 <img src="1" width="2" /> src="1 ...

  9. Zepto和Jquery区别

    ---恢复内容开始--- <zepto移动端事件> 1.$("#xx").tap(function(){ //tap在屏幕点击时触发 alert("sssss ...

  10. SharePoint 2013 - Designer Workflow

    另一篇文章 SharePoint Designer - Workflow 1. 可以定义每个Stage的名称,并将Stage名称显示在工作流状态字段,相比于SP2010时仅有的in progress ...