XML解析器介绍


Android中提供了三种方式来解析XML:

  1. SAX(simple API for XML)
  2. DOM(文档对象模型)
  3. 以及Android内部使用的Pull解析。

SAX(simple API for XML)解析器

SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。

SAX是事件驱动型的,SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

SAX解析器的优点

  • 解析速度快
  • 占用内存少

SAX解析器非常适合在Android移动设备中使用。

SAX解析器的缺点

  • 只能读取XML,无法修改。
  • 无法知道当前解析标签的上层标签及嵌套结构,仅仅知道当前解析的标签的名字和属性,要知道其他信息需要自己实现。
  • 无法随机访问某个标签。

DOM解析器

DOM(Document Object Model,文档对象模型)是W3C制定的一套规范标准,即规定了解析文件的接口。各种语言可以按照DOM规范去实现这些接口,给出解析文件的解析器。

DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。

DOM解析器的优点

  • 易用性强,使用简单
  • DOM在内存中以树形结构存放,因此检索和更新效率会更高
  • 适于修改XML结构

DOM解析器的缺点

  • 效率低
  • 解析速度慢
  • 内存占用量过高
  • 不适合大型文件

PULL解析器

PULL解析器是一个开源的java项目,既可以用在Android上,也可以用在java EE上,运行方式与SAX相似,都是基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。

PULL解析器的优点

  • 小巧轻便
  • 解析速度快
  • 简单易用
  • 非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器

PULL解析器的缺点

同SAX。

实战


我们将分别使用三种XML解析器来解析一个XML文件。

将要解析的XML文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<books><book id="1"><name>android</name></book><book id="2"><name>java</name></book><book id="3"><name>c++</name></book>
</books

SAX解析

public class SAXParserDemo {public List<Book> getBooks(InputStream instream) {try {//创建SAX解析工厂SAXParserFactory factory = SAXParserFactory.newInstance();//创建SAX解析器SAXParser paser = factory.newSAXParser();//设置解析器的相关特性,true表示开启命名空间特性paser.setProperty("http://xml.org/sax/features/namespaces",true);//创建事件处理程序BookPaser bookPaser = new BookPaser();//开始解析paser.parse(instream, bookPaser);//关闭输入流instream.close();//返回解析后的内容return bookPaser.getBooks();}catch (Exception e){e.printStackTrace();}return null;}//创建事件处理程序,也就是编写ContentHandler的实现类,一般继承自DefaultHandler类public final class BookPaser extends DefaultHandler {public List<Book> getBooks() {return books;}private List<Book> books = null;//当前解析的元素标签private String tagName = null; private Book Book = null;//遇到文档开始标记的时候创建Book集合@Overridepublic void startDocument () throws SAXException{books = new ArrayList<Book>();}//遇到元素节点开始时候的处理方法@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {tagName = localName;//如果遇到<Book>标记,则创建一个Book实例if ("Book".equals(tagName)) {Book = new Book();//取出标记内的属性Book.setId(new Integer(attributes.getValue(0)));}}//遇到文本节点时的操作@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {//文本节点必须前面要有元素节点开始标记if (tagName != null) {//取出文本节点的值String data = new String(ch, start, length);//如果前面的元素节点开始标记是nameif ("name".equals(tagName)) {//则将文本节点的值赋值给Book的nameBook.setName(data);}}}//遇到元素节点结束时候的操作@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {//如果遇到</Book>标记if ("Book".equals(localName)) {//则将创建完成的Book加入到集合中去books.add(Book);Book = null;//置空下一个Book}//置空已有标记,因为要解析下一个节点了tagName = null;}}
}

代码逻辑都包含在注释里了,SAX解析器是通过注册回调的方式实现解析逻辑的,我们的解析逻辑在DefaultHandler类型的子类中实现。

DOM解析

public class DomParserDemo {public List<Book> getBooks(InputStream instream) throws Exception {List<Book> books = new ArrayList<Book>();//创建DOM解析工厂DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//创建DON解析器DocumentBuilder dombuild = factory.newDocumentBuilder();//开始解析XML文档并且得到整个文档的对象模型Document dom = dombuild.parse(instream);//得到根节点<books>Element root = dom.getDocumentElement();//得到根节点下所有标签为<book>的子节点NodeList bookList = root.getElementsByTagName("book");//遍历book节点for (int i = 0; i < bookList.getLength(); i++) {//首先创建一个BookBook book = new Book();//得到本次Book元素节点Element bookElement = (Element) bookList.item(i);//得到Book节点中的IDbook.setId(new Integer(bookElement.getAttribute("id")));//得到Book节点下的所有子节点NodeList bookChilds = bookElement.getChildNodes();//遍历Book节点下的所有子节点for (int j = 0; j < bookChilds.getLength(); j++) {//如果是元素节点的话if (bookChilds.item(j).getNodeType() == Node.ELEMENT_NODE) {//得到该元素节点Element childElement = (Element) bookChilds.item(j); //如果该元素节点是name节点if ("name".equals(childElement.getNodeName())) {//得到name节点下的第一个文本子节点的值book.setName(childElement.getFirstChild().getNodeValue());}}}books.add(book);}return books;}
}

DOM的解析逻辑见注释。

PULL解析

public class PullParserDemo {public List<Book> getBooks(InputStream instream) throws Exception {List<Book> books = null;//当前处理对象Book book = null;//得到Pull解析器XmlPullParser parser = Xml.newPullParser();//设置输入流的编码parser.setInput(instream, "UTF-8");//得到第一个事件类型int eventType = parser.getEventType();//如果事件类型不是文档结束的话则不断处理事件while (eventType != XmlPullParser.END_DOCUMENT) {switch (eventType) {//如果是文档开始事件case (XmlPullParser.START_DOCUMENT)://初始化Book集合books = new ArrayList<Book>();break;//如果遇到标签开始case (XmlPullParser.START_TAG)://获得解析器当前元素的名称String tagName = parser.getName();//如果当前标签名称是<book>if ("book".equals(tagName)) {//创建一个bookbook = new Book();//将元素的属性值赋值给idbook.setId(new Integer(parser.getAttributeValue(0)));}//如果book已经创建完成if (book != null) {//如果当前节点标记是nameif ("name".equals(tagName)) {book.setName(new String(parser.nextText()));}}break;//如果遇到标签结束case (XmlPullParser.END_TAG)://如果是book标签结束if ("book".equals(parser.getName())) {//将book加入集合books.add(book);//置空book = null;}break;}//进入下一个事件处理eventType = parser.next();}return books;}
}

PULL解析是主动获取事件的,并且下一次事件的处理也由我们来调用触发。

至此,三种解析器的实例Demo已经完成,其实都不算复杂,按照Demo使用即可。

总结


本文分析了Android中,可使用的三种XML解析器,并对它们的实现逻辑及优缺点进行了分析和对比。

我们在实战部分,分别用三种解析器实现了Demo中XML文件的解析,代码注释详细的介绍了整个过程。

在Android中,推荐使用PULL解析器来解析XML文件,并且Android系统中,使用的XML解析器也是PULL解析器。

Android中XML的三种解析器分析、实战相关推荐

  1. xml的三种解析方式

    本篇博客重点介绍Android中三种解析XML的方式,包括PULL.SAX.DOM,当然不止这些,还可以用第三方的jar包提供的解析,只是这三种在Android中比较常用吧.再顺便介绍一下Androi ...

  2. XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较

    6月20日 XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较  1:DOM     DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准.DOM 是以层次结 ...

  3. python中变量名后的逗号_Python中逗号的三种作用实例分析

    本文实例讲述了Python中逗号的三种作用.分享给大家供大家参考.具体分析如下: 最近研究python  遇到个逗号的问题 一直没弄明白 今天总算搞清楚了 1.逗号在参数传递中的使用: 这种情况不多说 ...

  4. python逗号怎么用_Python中逗号的三种作用实例分析

    本文实例讲述了Python中逗号的三种作用.分享给大家供大家参考.具体分析如下: 最近研究python 遇到个逗号的问题 一直没弄明白 今天总算搞清楚了 1.逗号在参数传递中的使用: 这种情况不多说 ...

  5. Android中Video的三种播放方式的实现

     在Android中,我们有三种方式来实现视频的播放. 1.使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型. 2.使用VideoView来 ...

  6. Android解析XML的三种方式

    在Android中提供了三种解析XML的方式:DOM(Document Objrect Model),SAX(Simple API XML),以及Android推荐的Pull解析方式. 如图: 本篇博 ...

  7. Android中XML数据解析

    转载请注明出处:http://blog.csdn.net/yegongheng/article/details/38296207 XML初步 今天我们来学习另一种非常重要的数据交换格式-XML.XML ...

  8. xml文件的三种解析方式 DOM SAM PULL

    <?xml version="1.0" encoding="UTF-8"?> <root><student id="1& ...

  9. Java解析Xml的三种方式总结

    转自:http://blog.csdn.net/zjf280441589/article/details/50613881 XML解析技术有两种 DOM SAX DOM方式  根据XML的层级结构在内 ...

最新文章

  1. 40个出色的Wordpress cms插件
  2. MPB:中科院深圳先进院戴磊组小鼠粪便样本中16S拷贝数的定量检测
  3. BZOJ 4665: 小w的喜糖
  4. Quartz 入门详解
  5. C++ STL之min_element()与max_element()(取容器中的最大最小值)
  6. html 三大标签,网站三大标签的正确书写
  7. 拓端tecdat|R语言混合效应逻辑回归(mixed effects logistic)模型分析肺癌数据
  8. java 时间戳 重复_在Java中创建一个唯一的时间戳
  9. mysql 中电话号码_类型-电话号码和地址的mysql数据类型
  10. 航空429接口测试工装研究
  11. 电子设计教程33:RC桥式正弦波振荡电路
  12. mac本在终端查看本地ip
  13. php 百度地图导航代码,百度地图API自动定位和3种导航
  14. 解决Win2000 不能启动的几种方法
  15. 开机黑屏显示html,电脑开机显示display going to sleep怎么办?
  16. opencv ipcam
  17. 当你开始听不清这个世界的声音
  18. php 中英文查询字数,php统计中英文混合的文章字数
  19. python小课堂25_Python入门第25课——小案例之随机数(只读课堂)
  20. cocos2dx:重力加速度,自由落体:利用update()就能快速实现精灵自由落体运动

热门文章

  1. 中正平和的机器人学笔记——5. 机械臂动力学
  2. 频率学派(似然估计)与贝叶斯学派(后验估计)
  3. 超过2t硬盘分区_磁盘挂载问题:Fdisk最大只能创建2T分区的盘,超过2T使用parted...
  4. 二次安检!自带文具!多地要求提前一小时到考场!
  5. CNN卷积神经网络详解
  6. 监听android home键的实现方式
  7. 树莓派更换pip源为国内
  8. html在线绘制图形,html5-Canvas可以在web中绘制各种图形
  9. 游客检票 - C/C++ 变量及简单数据类型
  10. 微信开发系列(六)_js调用微信扫码