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= ...
随机推荐
- TOJ 1883 Domino Effect
Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...
- Apache-Maven 的安装及配置
一. 下载 没有 Maven 的朋友可以去 Apache 的官网下载一个 Maven, Apache-Maven 官网下载 : https://maven.apache.org/download.cg ...
- SpringSecurity 3.2入门(7)自定义权限控制介绍
总结Spring Security的使用方法有如下几种: 一种是全部利用配置文件,将用户.权限.资源(url)硬编码在xml文件中. 二种是用户和权限用数据库存储,而资源(url)和权限的对应关系硬编 ...
- 1.net平台
.net/dotnet:一般指的是.Net Framework框架,是一种平台,一种技术. .net Framewoek框架是.net平台不可缺少的一部分,它提供了一个稳定的运行环境来保证.net ...
- 【tomcat】关于tomcat的使用:将tomcat加入系统服务列表
一.下载TOMCAT 选择合适的版本进行下载: http://tomcat.apache.org/ 解压zip文件得到tomcat目录: 二.添加CATALINA_HOME到环境变量 service. ...
- 3、HTML属性
属性的意义是为HTML提供附加信息. 属性中,名称和值总是成对出现.比如 <img src="1" width="2" /> src="1 ...
- 数据结构复习之C语言malloc()动态分配内存概述
#include <stdio.h> #include <malloc.h> int main(void) { ] = {, , , , }; // 计算数组元素个数 ]); ...
- 工作流一期上线原创小故事——【加签】OR【不准】
亲!您有过选择[加签]还是审核[不准]的烦恼吗? 加签分为:向前加签和向后加签,这个相信大家都很熟悉了吧. 审核分为:准和不准,就是√和×,这个相信大家也很熟悉了. 提示①:相邻的2个人审核时,如果意 ...
- ASP.NET MVC 音乐商店 - 0 概览
这是一个系列文章,原文内容出自微软的 MusicStore. 首先对原文内容进行了简单的翻译,以方便大家参考,另外对于其中的部分内容,也进行了简单的分析,使用的 Visual Studio 也换成了中 ...
- matlab练习程序(随机游走图像)
随机游走类似布朗运动,就是随机的向各个方向走吧. 虽然代码没什么技术含量,不过产生的图像实在太漂亮了,所以还是贴上来吧. 产生的图像: matlab代码如下: clear all;close all; ...