Android下Xml解析技术(一)、SAX解析Xml文件

2024-02-28 09:48
文章标签 xml android 技术 解析 sax

本文主要是介绍Android下Xml解析技术(一)、SAX解析Xml文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Xml文件有许多解析方式,在学习J2EE中就学过很多,比如DOM,DOM4j,SAX,JDOM等等。

 

DOM:文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。

JDOM:JDOM是一种使用 XML 的独特 Java 工具包,用于快速开发 XML 应用程序。它的设计包含 Java 语言的语法乃至语义。

DOM4j:dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。

SAX:SAX(Simple API for XML)是基于事件驱动的 XML 处理模式,主要是围绕着事件源以及事件处理器(或者叫监听器)来工作的。

在Android中,比较常见的有SAX,DOM和Pull这三种解析方式。并且Android上对XML解析的支持是相当强大的,看一下Android中和XML 解析相关的包:

 

1. android.sax

这是Android SDK提供的sax解析的包,因为可以对具体的Element设置监听进行处理,因此有更好鲁棒性。

2. android.util.Xml

这是android.util包中的其中一个类,提供XML相关的实用方法,而且都是public static形式的类方法,即可以直接以类名调用。

3. javax.xml.parsers

这是使用原来Java SDK用于xml处理的API,即JAXP(Java API for XML Processing),主要提供了SAX和DOM方式解析XML的工厂方法。

4. org.w3c.dom

提供具体的和DOM方式解析XML相关的接口,如Document、 Element等。

5. org.xml.sax

提供具体的和SAX方式解析XML相关的接口,如XMLReader及 4个处理用的 Handler 等。

6. org.xml.sax.helpers

提供SAX的帮助类,以便更方便的用来解析,比如实现了SAX的4个处理用的Handler接口的 DefaultHandler ,用来更方便使用 XML 过滤器 XMLFilter 的 XMLFilterImpl,和用于更方便创建XMLReader的XMLReaderFactory等。

7. org.xmlpull.v1

提供Pull方式解析XML的接口XmlPullParser和用于写 XML 的 XmlSerializer 等。

以上就是Android提供的和XML读写相关的一些包,在这个学习系列中我们将对这些包的功能进行具体的介绍,并依次使用这些SAX解析的方式完成读取XML地震数据的Demo 例子。

 

 

下面就看看这三种解析方法的第一种:SAX解析技术

 

SAX(Simple API for XML)是基于事件驱动的 XML 处理模式,主要是围绕着事件源以及事件处理器(或者叫监听器)来工作的。一个可以产生事件的对象被称为事件源,而可以针对事件产生响应的对象就被叫做事件处理器。事件源和事件处理器是通过在事件源中的事件处理器注册方法连接的。这样当事件源产生事件后(比如碰到XML元素的开始和结束等),调用事件处理器(由许多回调函数组成)相应的处理方法,一个事件就获得了处理。当然在事件源调用事件处理器中特定方法的时候,会传递给事件处理器相应事件的状态信息(即回调函数中的参数),这样事件处理器才能够根据事件信息来决定自己的行为。

其中常用的事件处理回调函数有用于文档处理的

文档开始:startDocument(),

文档结束:endDocument(),

XML元素开始:startElement(String uri, String localName, String qName,Attributes attributes),

XML元素内容:characters(char[] ch, int start, int  length) ,

XML元素结束:endElement(String uri, String localName, String qName),

还有解析错误的回调函数error(SAXParseException exception)等。

 

 

在Android系统中,提供了两种SAX解析的包,一种是原来Java SDK就有的用于XML处理的API(称为JAXP:Java API for XML Processing,包含了SAX和DOM两者相关的API),相关内容在包javax.xml.parsers中。还有一种是经过了Android SDK包装了之后的sax包,相关内容在包android.sax中。

 

这部分我们先来学习原来Java SDK就有的用SAX方式处理XML的相关方法。在javax.xml.parsers包中,和SAX相关的为两个类:SAX解析器工厂SAXParserFactory和SAX解析器SAXParser。SAXParserFactory有set方法和get方法可以设置和获取一些配置选项,其中最重要的是调用newSAXParser()创建解析器SAXParser类的实例。SAXParser类包装了底层的SAX解析器(org.xml.sax.XMLReader 的实例),即SAXParser实例调用parse方法进行XML解析时,实际上会调用底层具体的org.xml.sax包中的XMLReader。SAXParser实例也可以通过调用getXMLReader()方法获得底层的XMLReader实例,一旦获得该实例,就可以按XMLReader方式使用更一般和具体的SAX方法。

 

通过以上的介绍我们知道org.xml.sax包是底层具体的负责SAX解析相关的内容,并且为上层javax.xml.parsers包提供SAX解析器等相关调用。下面我们就具体介绍一下用SAX进行解析的步骤。

在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parse()方法来开始解析XML文档并根据文档内容产生事件。而事件处理器则是org.xml.sax包中的ContentHandler,DTDHandler,ErrorHandler,以及 EntityResolver这四个接口。它们分别处理事件源在解析过程中产生的不同种类的事件(其中主要的为ContentHandler,处理和文档内容相关的事件)。 而事件源XMLReader和这四个事件处理器的连接是通过在XMLReader中的相应的事件处理器注册方法set***()来完成的。

因此概况一下具体步骤为:

1. 实现一个或多个处理器接口(ContentHandler, ErrorHandler, DTDHandler ,or EntityResover)

2. 创建一个XMLReader类的实例

3. 在新的XMLReader实例中通过大量的set*****() 方法注册一个事件处理器的实例

4. 调用XMLReader的parse()方法来处理文档启动解析

 

 

以上部分的介绍是指使用org.xml.sax包中提供的SAX解析的相关接口时的用法,但是一般常用并且比较方便的为使用javax.xml.parsers包提供的SAX工厂类SAXParserFactory创建SAXParser实例,并且创建一个继承org.xml.sax.helpers包中的DefaultHandler的类,用于实现具体的SAX事件的处理逻辑,DefaultHandler类提供了SAX中ContentHandler,DTDHandler,ErrorHandler,以及 EntityResolver这四个接口的所有回调方法默认的空实现,因此我们继承这个类后可以只覆盖我们需要的回调函数即可。然后调用SAXParser实例的parse方法进行解析,用来解析的xml数据的形式可以为InputStreams, Files, URLs, and SAX InputSources等四种形式。

实现步骤和上面类似:

1. 在继承DefaultHandler的类里面重写需要的回调函数

2. 创建SAXParser实例

3. SAXParser实例调用parse方法启动解析

 

 

我们要解析这样一个简单的xml文件 test.xml

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <persons>

  3. <person id="1">

  4. <name>Lucy</name>

  5. <age>15</age>

  6. </person>

  7. <person id="2">

  8. <name>Tim</name>

  9. <age>20</age>

  10. </person>

  11. </persons>

 

xml文件中的节点分为两种,元素节点和文本节点。

元素节点指的是 <>中的元素

文本节点指的是 元素与元素之间的文本

解析xml文件时 ,应该从开始一步步往下解析, 对自己感兴趣的触发事件,在回调方法里面的写好事件处理。

一、在继承DefaultHandler的类里面重写需要的回调函数

一般需要重写5个方法:

startDocument()  :开始文档的回调方法

endDocument() :结束文档的回调方法

startElement(String uri, String localName, String qName, Attributes attributes) :开始元素节点的回调方法

参数:

uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。

localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。

qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。

attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。

 

endElement(String uri, String localName, String qName)

参数:

uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。

localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。

qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。

 

characters(char[] ch, int start, int length)

参数:

ch - 字符。

start - 字符数组中的开始位置。

length - 从字符数组中使用的字符数。

在实际操作中根据需求,在API中参照更多的方法。

 

 
  1. package com.tao.xmlpaser;

  2.  
  3. import java.util.ArrayList;

  4. import java.util.List;

  5.  
  6. import org.xml.sax.Attributes;

  7. import org.xml.sax.SAXException;

  8. import org.xml.sax.helpers.DefaultHandler;

  9.  
  10. public class SaxHandler extends DefaultHandler {

  11.     private String tag;// 标志标签的名称

  12.     private List<Person> persons;

  13.     private Person person;

  14.  
  15.     // 开始文档的回调方法

  16.     @Override

  17.     public void startDocument() throws SAXException {

  18.         super.startDocument();

  19.         persons = new ArrayList<Person>();

  20.     }

  21.  
  22.     // 结束文档的回调方法

  23.     @Override

  24.     public void endDocument() throws SAXException {

  25.         super.endDocument();

  26.     }

  27.  
  28.     // 开始元素的回调方法

  29. //注意:由于有些环境不一样,有时候第二个参数有可能为空,所以可以使用第三个参数,因此在解析前,先调用一下看哪个参数能用,

  30.      @Override

  31.     public void startElement(String uri, String localName, String qName, Attributes attributes)

  32.             throws SAXException {

  33.         super.startElement(uri, localName, qName, attributes);

  34.         if ("person".equals(qName)) {

  35.             person = new Person();

  36.             person.setId(new Integer(attributes.getValue(0)));

  37.         } else if ("name".equals(qName)) {

  38.             tag = qName;

  39.         } else if ("age".equals(qName)) {

  40.             tag = qName;

  41.         }

  42.     }

  43.  
  44.     // 结束元素的回调方法

  45.     @Override

  46.     public void endElement(String uri, String localName, String qName) throws SAXException {

  47.         super.endElement(uri, localName, qName);

  48.         tag = null;

  49.         if ("person".equals(qName)) {

  50.             persons.add(person);

  51.             person = null;

  52.         }

  53.     }

  54.  
  55.     // 解析到文本节点回调方法

  56.     @Override

  57.     public void characters(char[] ch, int start, int length) throws SAXException {

  58.         super.characters(ch, start, length);

  59.         if (tag == null)

  60.             return;

  61.         if ("name".equals(tag)) {

  62.             person.setName(new String(ch, start, length));

  63.         }

  64.         if ("age".equals(tag)) {

  65.             person.setAge(new Integer(new String(ch, start, length)));

  66.         }

  67.     }

  68.  
  69.     // 返回解析的数据

  70.     public List<Person> getResult() {

  71.         return persons;

  72.     }

  73. }

 

 

 

Person Mode类

 

 
  1. package com.tao.xmlparse;

  2.  
  3.  
  4. public class Person {

  5. private int id;

  6. private String name;

  7. private int age;

  8. public Person() {

  9. }

  10.  
  11. public Person( String name, int age) {

  12. this.name = name;

  13. this.age = age;

  14. }

  15.  
  16. public Person(int id, String name, int age) {

  17. this.id = id;

  18. this.name = name;

  19. this.age = age;

  20. }

  21.  
  22. public int getId() {

  23. return id;

  24. }

  25. public void setId(int id) {

  26. this.id = id;

  27. }

  28. public String getName() {

  29. return name;

  30. }

  31. public void setName(String name) {

  32. this.name = name;

  33. }

  34. public int getAge() {

  35. return age;

  36. }

  37. public void setAge(int age) {

  38. this.age = age;

  39. }

  40. }


 

 

 

 

2. 创建SAXParser实例    3. SAXParser实例调用parse方法启动解析

 

 

 

 

 
  1. public void saxParseXml() throws ParserConfigurationException, SAXException, IOException{

  2. //构造解析器,创建SAXParser实例

  3. SAXParserFactory factory=SAXParserFactory.newInstance();

  4. SAXParser parser=factory.newSAXParser();

  5. //获得xml文件的输入流

  6. InputStream inputStream=getClass().getClassLoader().getResourceAsStream("test.xml");

  7. //初始化hanlder对象

  8. SaxHandler handler=new SaxHandler();

  9. //开始解析

  10. parser.parse(inputStream, handler);

  11. //返回解析结果,然后输出

  12. List<Person> persons=handler.getResult();

  13. for (Person p:persons) {

  14. System.out.println(p.getId()+"--"+p.getName()+"---"+p.getAge());

  15. }

  16. }


 

在用Sax解析的时候最需要重视的一点就是不要把那些<节点>之间的空白忽略就好!

这篇关于Android下Xml解析技术(一)、SAX解析Xml文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/755116

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时