解析Xml文件的三种方式及其特点
1、Sax解析(simple api for xml)
使用流式处理的方式,它并不记录所读内容的相关信息。它是一种以事件为驱动的XML API,解析速度快,占用内存少。使用回调函数来实现。

1 class MyDefaultHander extends DefaultHandler{
2 private List<Student> list;
3 private Student student;
4
5 @Override
6 public void startDocument() throws SAXException {
7 super.startDocument();
8 list=new ArrayList<>();
9 }
10
11 @Override
12 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
13 super.startElement(uri, localName, qName, attributes);
14 if(qName.equals("student")){
15 student=new Student();
16
17 }
18 preTag=qName;
19 }
20
21 @Override
22 public void endElement(String uri, String localName, String qName) throws SAXException {
23 if(qName.equals("student")){
24 list.add(student);
25 }
26 preTag=null;
27 }
28
29 @Override
30 public void characters(char[] ch, int start, int length) throws SAXException {
31 if(preTag!=null){
32 if(preTag.equals("id")){
33 student.setId(Integer.parseInt(new String(ch,start,length)));
34 }else if(preTag.equals("name")){
35 student.setName(new String(ch,start,length));
36 }else if(preTag.equals("age")){
37 student.setAge(Integer.parseInt(new String(ch,start,length)));
38 }
39 }
40 }
41 public List<Student> getStudents(){
42 return list;
43 }
44 }
45 public List<Student> sax_parser(){
46 List<Student> list=null;
47 try {
48 SAXParser parser= SAXParserFactory.newInstance().newSAXParser();
49 InputStream is= getAssets().open("student.xml");
50 MyDefaultHander hander=new MyDefaultHander();
51 parser.parse(is,hander);
52 list= hander.getStudents();
53 } catch (ParserConfigurationException e) {
54 e.printStackTrace();
55 } catch (SAXException e) {
56 e.printStackTrace();
57 } catch (IOException e) {
58 e.printStackTrace();
59 }
60 return list;
61 }

2、Dom解析
DOM(Document Object Model) 是一种用于XML文档的对象模型,可用于直接访问XML文档的各个部分。它是一次性全部将内容加载在内存中,生成一个树状结构,它没有涉及回调和复杂的状态管理。 缺点是加载大文档时效率低下。

1 public List<Student> DOM_parser(){
2 DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
3 List<Student> list=null;
4 try {
5 Document dom= factory.newDocumentBuilder().parse(getAssets().open("student.xml"));
6 Element element= dom.getDocumentElement();
7 NodeList nodeList= element.getChildNodes();
8 list=new ArrayList<>();
9 for(int i=0;i<nodeList.getLength();i++){
10 Log.i(TAG, "DOM_parser: "+nodeList.item(i).getNodeName());
11 if(nodeList.item(i).getNodeName().equals("student")){
12 NodeList childList= nodeList.item(i).getChildNodes();
13 Student stu=new Student();
14 for(int k=0;k<childList.getLength();k++){
15 if(childList.item(k).getNodeName().equals("id")){
16 stu.setId(Integer.parseInt(childList.item(k).getFirstChild().getNodeValue()));//注意直接getNodeValue()永远返回null,需调用getFirsetChild()后调用getNodeValue()
17 }else if(childList.item(k).getNodeName().equals("name")){
18 stu.setName(childList.item(k).getFirstChild().getNodeValue());
19 }else if(childList.item(k).getNodeName().equals("age")){
20 stu.setAge(Integer.parseInt(childList.item(k).getFirstChild().getNodeValue()));
21 }
22 }
23 list.add(stu);
24 }
25 }
26 } catch (SAXException e) {
27 e.printStackTrace();
28 } catch (IOException e) {
29 e.printStackTrace();
30 } catch (ParserConfigurationException e) {
31 e.printStackTrace();
32 }
33 return list;
34 }

3、pull解析(android 推荐)
Pull内置于Android系统中。也是官方解析布局文件所使用的方式。Pull与SAX有点类似,都提供了类似的事件,如开始元素和结束元素。不同的是,SAX的事件驱动是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用相应的方法。而Pull解析器并没有强制要求提供触发的方法。因为他触发的事件不是一个方法,而是一个数字。它使用方便,效率高。

1 public List<Student> Xml_pull_parser(){
2 List<Student> list=null;
3 XmlPullParser parser= Xml.newPullParser();
4 try {
5 parser.setInput(getAssets().open("student.xml"),"UTF-8");
6 int event_code= parser.getEventType();
7 Student student=null;
8 while (event_code!=XmlPullParser.END_DOCUMENT){
9 switch (event_code){
10 case XmlPullParser.START_DOCUMENT:
11 list=new ArrayList<>();
12 break;
13 case XmlPullParser.START_TAG:
14 if(parser.getName().equals("student")){
15 student=new Student();
16 }
17 if(student!=null){
18 if(parser.getName().equals("id")){
19 // Log.i(TAG, "Xml_pull_parser: id="+parser.getText());
20 student.setId( Integer.parseInt(parser.nextText()));
21 }else if(parser.getName().equals("name")){
22 student.setName(parser.nextText());
23 }else if(parser.getName().equals("age")){
24 student.setAge(Integer.parseInt(parser.nextText()));
25 }
26 }
27 break;
28 case XmlPullParser.END_TAG:
29 if(parser.getName().equals("student")){
30 list.add(student);
31 student=null;
32 }
33 break;
34 }
35 event_code= parser.next();
36
37 }
38 } catch (XmlPullParserException e) {
39 e.printStackTrace();
40 } catch (IOException e) {
41 e.printStackTrace();
42 }
43 return list;
44 }
DOM、SAX、PULL三类方式对比
DOM方式
- 原理:基于文档驱动,是先把dom全部文件读入到内存中,构建一个主流内存的树结构,然后使用DOM的API遍历所有数据,调用API检索想要的数据和操作数据。
所以,DOM方式的优缺点是: - 特点:
优点:整个文档树存在内存中,可对XML文档进行操作:删除、修改等等;可多次访问已解析的文档;由于在内存中以树形结构存放,因此检索和更新效率会更高。;
缺点:解析 XML 文件时会将整个 XML 文件的内容解析成树型结构存放在内存中并创建新对象,比较消耗时间和内存; - 使用情境
对于像手机这样的移动设备来讲,内存是非常有限的,在XML文档比较小、需要对解析文档进行一定的操作且一旦解析了文档需要多次访问这些数据的情况下可以考虑使用DOM方式,因为其检索和解析效率较高
SAX方式
- 原理:基于事件驱动,在读取XML文档内容时,事件源顺序地对文档进行扫描,当扫描到文档的开始与结束(Document)标签、节点元素的开始与结束(Element)标签时,直接调用对应的方法,并将状态信息以参数的形式传递到方法中,然后我们可以依据状态信息来执行相关的自定义操作。
- 特点:
优点:解析效率高、占存少、灵活性高
缺点:解析方法复杂(API接口复杂),代码量大;可拓展性差:无法对 XML 树内容结构进行任何修改 - 使用情境
适用于需要处理大型 XML 文档、性能要求较高、不需要对解析文档进行修改且不需要对解析文档多次访问的场合
PULL方式
- 原理:PULL的解析方式与SAX解析类似,都是基于事件的模式。
PULL提供了开始元素和结束元素。当某个元素开始时,我们可以调用parser.nextText从XML文档中提取所有字符数据,与SAX不同的是,在PULL解析过程中触发相应的事件调用方法返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法从而执行代码。当解释到一个文档结束时,自动生成EndDocument事件。 特点:
优点:SAX的优点PULL都有,而且解析方法比SAX更加简单
缺点:可拓展性差:无法对 XML 树内容结构进行任何修改使用情境
适用于需要处理大型 XML 文档、性能要求较高、不需要对解析文档进行修改且不需要对解析文档多次访问的场合
同样的使用情景,在SAX和PULL解析方法中,更加推荐PULL方法
DOM、SAX、PULL三类方式对比
DOM方式
- 原理:基于文档驱动,是先把dom全部文件读入到内存中,构建一个主流内存的树结构,然后使用DOM的API遍历所有数据,调用API检索想要的数据和操作数据。
所以,DOM方式的优缺点是: - 特点:
优点:整个文档树存在内存中,可对XML文档进行操作:删除、修改等等;可多次访问已解析的文档;由于在内存中以树形结构存放,因此检索和更新效率会更高。;
缺点:解析 XML 文件时会将整个 XML 文件的内容解析成树型结构存放在内存中并创建新对象,比较消耗时间和内存; - 使用情境
对于像手机这样的移动设备来讲,内存是非常有限的,在XML文档比较小、需要对解析文档进行一定的操作且一旦解析了文档需要多次访问这些数据的情况下可以考虑使用DOM方式,因为其检索和解析效率较高
SAX方式
- 原理:基于事件驱动,在读取XML文档内容时,事件源顺序地对文档进行扫描,当扫描到文档的开始与结束(Document)标签、节点元素的开始与结束(Element)标签时,直接调用对应的方法,并将状态信息以参数的形式传递到方法中,然后我们可以依据状态信息来执行相关的自定义操作。
- 特点:
优点:解析效率高、占存少、灵活性高
缺点:解析方法复杂(API接口复杂),代码量大;可拓展性差:无法对 XML 树内容结构进行任何修改 - 使用情境
适用于需要处理大型 XML 文档、性能要求较高、不需要对解析文档进行修改且不需要对解析文档多次访问的场合
PULL方式
- 原理:PULL的解析方式与SAX解析类似,都是基于事件的模式。
PULL提供了开始元素和结束元素。当某个元素开始时,我们可以调用parser.nextText从XML文档中提取所有字符数据,与SAX不同的是,在PULL解析过程中触发相应的事件调用方法返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法从而执行代码。当解释到一个文档结束时,自动生成EndDocument事件。 特点:
优点:SAX的优点PULL都有,而且解析方法比SAX更加简单
缺点:可拓展性差:无法对 XML 树内容结构进行任何修改使用情境
适用于需要处理大型 XML 文档、性能要求较高、不需要对解析文档进行修改且不需要对解析文档多次访问的场合
同样的使用情景,在SAX和PULL解析方法中,更加推荐PULL方法
解析Xml文件的三种方式及其特点的更多相关文章
- 解析Xml文件的三种方式
1.Sax解析(simple api for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用回调函数来实现. clas ...
- 解析xml文件的四种方式
什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没 ...
- Android-----解析xml文件的三种方式
SAX解析方法介绍: SAX(Simple API for XML)是一个解析速度快并且占用内存少的XML解析器,非常适合用于Android等移动设备.SAX解析XML文件采用的是事件驱动,也就是说, ...
- 解析XML文件的几种方式及其比较
解析xml文件目前比较流行的主要有四种方式: 1. DOM(Document Object Model)它把整个XML文档当成一个对象加载到内 存,不管文档有多大.它一般处理小文件 2.SAX(Si ...
- android中解析文件的三种方式
android中解析文件的三种方式 好久没有动手写点东西了,最近在研究android的相关技术,现在就android中解析文件的三种方式做以下总结.其主要有:SAX(Simple API fo ...
- 解析XML文件的几种常见操作方法—DOM/SAX/DOM4j
解析XML文件的几种常见操作方法—DOM/SAX/DOM4j 一直想学点什么东西,有些浮躁,努力使自己静下心来看点东西,哪怕是回顾一下知识.看到了xml解析,目前我还没用到过.但多了解一下,加深点记忆 ...
- java读取XML文件的四种方式
java读取XML文件的四种方式 Xml代码 <?xml version="1.0" encoding="GB2312"?> <RESULT& ...
- Velocity中加载vm文件的三种方式
Velocity中加载vm文件的三种方式: a. 加载classpath目录下的vm文件 /** * 初始化Velocity引擎 * --VelocityEngine是单例模式,线程安全 * @th ...
- 前端js,css文件合并三种方式,bat命令
前端js,css文件合并三种方式,bat命令 前端js文件该如何合并三个方式如下:1. 一个大文件,所有js合并成一个大文件,所有页面都引用它.2. 各个页面大文件,各自页面合并生成自己所需js的大文 ...
随机推荐
- nginx location 语法
location 语法location 有”定位”的意思, 根据Uri来进行不同的定位.在虚拟主机的配置中,是必不可少的,location可以把网站的不同部分,定位到不同的处理方式上.比如, 碰到.p ...
- Python的进度条的制作
import sys,time #导入模块 for i in range(50): #进度条的长度 sys.stdout.write("#") #进度条的内容,这里要注意了,pyc ...
- centos虚拟机启用网卡
CentOS虚拟机安装成功后,默认开机未启用网关,通过修改配置文件,启用网卡 编辑系统配置文件,虚拟机完成后,系统安装了一个默认的网卡,即eth0,其配置文件的路径为/etc/sysconfig/ne ...
- 应验log4j.xml时不能找到log4j.dtd
原因分析:log4j.xml中使用log4j的DTD验证其格式的有效性"<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd&quo ...
- 分享知识-快乐自己:mybatis 主键回调
以下两种方式实现 主键回掉方式. <!--添加用户信息:主键回调--> <insert id="insertUser" useGeneratedKeys=&quo ...
- 分享知识-快乐自己:springboot之thymeleaf (1):简单的thymeleaf例子
之前搞springboot时,发现spring很推荐thymeleaf,所以看了看学了学,感觉不错,做个笔记先. 做个简单和例子,项目是springboot,所以引入themeleaf相关包 pom. ...
- PHP 常量、PHP 变量全解析(超全局变量、变量的8种数据类型等)
常量特点 常量一旦被定义就无法更改或撤销定义. 常量名不需要开头的$ 与变量不同,常量贯穿整个脚本是自动全局的. 作用域不影响对常量的访问 常量值只能是字符串或数字 设置 PHP 常量 如需设置常量, ...
- OpenCV——径向模糊
参考来源: 学习OpenCV:滤镜系列(5)--径向模糊:缩放&旋转 // define head function #ifndef PS_ALGORITHM_H_INCLUDED #defi ...
- I.MX6 USB Camera
/************************************************************************* * I.MX6 USB Camera * 说明: ...
- dubbo monitor simple 监控原理分析
监控机制: 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心.监控中心负责统计各服务调用次数,调用时间等. 监控元数据存储目录结构: --dubbo.jetty ...