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. LUM使用常规命令

    查看日志 tail -f /var/log/messages LUM使用常规命令再列出一下######------ 软件操作方法:* 关闭LUM及所有组件:lu-stop* 启动LUM及所有组件:lu ...

  2. iOS App被拒原因以及解决方案总结。

    Guideline 1.2 - Safety - User Generated Content Your app enables the display of user-generated conte ...

  3. 分享知识-快乐自己:Spring切入点的表达式和通知类型

    1.切入点的表达式 表达式格式: execution([修饰符] 返回值类型 包名.类名.方法名(参数)) 其他的代替: <!-- 完全指定一个方法 --> <!-- <aop ...

  4. 机器学习(十七)— SVD奇异值分解

    奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...

  5. Python调试时__name__ =='__main__'的妙用

    # python 文件自己运行,__name__的值就会等于__main__# 别的文件导入执行时,变成了导入文件的名字 例如: niuniu.py文件中,文件自己执行时,__name__的值就是__ ...

  6. 用JavaScript实现表单按回车自动提交

    JavaScript实现表单form1按回车自动提交代码如下: <script type="text/javascript"> function submitMe() ...

  7. AAC头部格式

    一共有2种AAC头格式,一种是StreamMuxConfig,另一种是AudioSpecificConfig 1.AudioSpecificConfig 读写header的代码参考    ffmpeg ...

  8. pytorch--cpu与gpu load时相互转化

    pytorch------cpu与gpu load时相互转化 torch.load(map_location=)学习 将gpu改为cpu时,遇到一个报错:RuntimeError: Attemptin ...

  9. Oracle RAC TAF 无缝failover

    理论背景: TAF( Transparent Application Failover ) allows oracle clients to reconnect to a surviving inst ...

  10. Android 开发:开源库Speex支持arm64的动态库文件

    随着处理器制造工艺的不断进步,和Android系统的不断发展,最近出了arm64-v8a的架构,由于项目中用到了speex的第三方语音编解码的动态库,其他架构的处理器暂不用说,一切正常,唯独到arm6 ...