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文件的三种方式及其特点的更多相关文章

  1. 解析Xml文件的三种方式

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

  2. 解析xml文件的四种方式

    什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没 ...

  3. Android-----解析xml文件的三种方式

    SAX解析方法介绍: SAX(Simple API for XML)是一个解析速度快并且占用内存少的XML解析器,非常适合用于Android等移动设备.SAX解析XML文件采用的是事件驱动,也就是说, ...

  4. 解析XML文件的几种方式及其比较

    解析xml文件目前比较流行的主要有四种方式: 1. DOM(Document Object Model)它把整个XML文档当成一个对象加载到内  存,不管文档有多大.它一般处理小文件 2.SAX(Si ...

  5. android中解析文件的三种方式

    android中解析文件的三种方式     好久没有动手写点东西了,最近在研究android的相关技术,现在就android中解析文件的三种方式做以下总结.其主要有:SAX(Simple API fo ...

  6. 解析XML文件的几种常见操作方法—DOM/SAX/DOM4j

    解析XML文件的几种常见操作方法—DOM/SAX/DOM4j 一直想学点什么东西,有些浮躁,努力使自己静下心来看点东西,哪怕是回顾一下知识.看到了xml解析,目前我还没用到过.但多了解一下,加深点记忆 ...

  7. java读取XML文件的四种方式

    java读取XML文件的四种方式 Xml代码 <?xml version="1.0" encoding="GB2312"?> <RESULT& ...

  8. Velocity中加载vm文件的三种方式

    Velocity中加载vm文件的三种方式: a.  加载classpath目录下的vm文件 /** * 初始化Velocity引擎 * --VelocityEngine是单例模式,线程安全 * @th ...

  9. 前端js,css文件合并三种方式,bat命令

    前端js,css文件合并三种方式,bat命令 前端js文件该如何合并三个方式如下:1. 一个大文件,所有js合并成一个大文件,所有页面都引用它.2. 各个页面大文件,各自页面合并生成自己所需js的大文 ...

随机推荐

  1. 大话设计模式--模板方法模式 TemplateMethod -- C++ 实现

    1. 模板方法模式: 定义一个操作中的算法骨架,而将一些操作延迟到子类, 模板方法模式使得子类可以不改变一个算法的结构既可以重定义该算法的某些特定步骤. 当不变和可变的行为在方法的子类实现中混在一起的 ...

  2. linux 软件包的命名规则

     linux软件包的命名规则 eg:主包       bind-9.7.1-1.el7.i586.rpm 子包 bind-libs-9.7.1-1.el7.i586.rpm bind-utils-9. ...

  3. python第六篇:Python复制超大文件、复制二进制文件

    Python文件复制 # 写程序实现复制文件的功能 # 要求: # 1. 源文件路径和目标文件路径需要手动输入 # 2. 要考虑文件关闭的问题 # 3. 要考虑复制超大文件的问题 # 4. 要能复制二 ...

  4. dos命令行中不同磁盘的调转

    windows下,dos中不同磁盘的跳转: 直接 盘符+回车: 如跳转到d盘: D:回车即可 : Microsoft Windows [版本 10.0.10586] (c) 2015 Microsof ...

  5. vi 常用编辑命令

    什么是vi: vi是Linux/Unix底下最常用的文本编辑器,可以理解为和Windows下的txt一样,咱们一般操作linux服务器的时候都是没有图形化界面的, 怎么移动光标,到哪个位置,替换修改什 ...

  6. MicroMessage的动态操作(第二步)

    现在开始将静态页面转化成动态页面.将页面上的信息转化成 数据库提供的信息. 建立jdbc获取数据库连接,并设置一个查询sql语句,查出所有结果.但是因为查询结果rs包含全表信息,是多行. 为了保存查询 ...

  7. QListWidget拖放

    setDragEnabled() 允许拖 setAcceptDrops()允许放 setDragDropMode(QAbstractItemView.DragDrop)设置拖拽模式 setSelect ...

  8. linux命令学习笔记(0):man命令

    Linux提供了丰富的帮助手册,当你需要查看某个命令的参数时不必到处上网查找,只要man一下即可. Linux的man手册共有以下几个章节: 代號 代表內容 使用者在shell中可以操作的指令或可执行 ...

  9. Poj 1401 Factorial(计算N!尾数0的个数——质因数分解)

    一.Description The most important part of a GSM network is so called Base Transceiver Station (BTS). ...

  10. 使用cmd命令行方式登录ftp上传下载数据

    部分用户在使用ftp工具登录空间上传下载过程中经常会遇到各种问题,如主动模式,被动模式,以及其他导致无法登陆ftp .上传数据.下载数据的问题,这时候不妨使用一下命令行方式.命令行下可以避免很多由于f ...