SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。

SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。

SAX相关类及API

DefaultHandler:是一个事件处理器,可以接收解析器报告的所有事件,处理所发现的数据。它实现了EntityResolver接口、DTDHandler接口、ErrorHandler接口和ContentHandler接口。这几个接口代表不同类型的事件处理器。

利用SAX解析XML,实际上只需要继承DefaultHandler类,然后重写几个关键性方法即可。一般我们需要重写的方法是startDocument、startElement、characters、endElement和endDocument方法。

API解释:

 import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; public class MyParser extends DefaultHandler{ /**
* 当文档开始解析时此函数被调用
*
* 通常我们需要在这里面做一些初始化的工作,比如分配某些资源
*/
@Override
public void startDocument() throws SAXException {
super.startDocument();
} /**
* 当扫描到文档元素节点起始标志时被调用
*
* 通常我们需要做一下标记,或者分配节点资源。
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
} /**
* 扫描到元素节点中的字符串内容时调用此函数
* @param ch 代表元素内容的字符数组(实测时候并不完全表示元素内容,不过这不影响)
* @param start 能够使用的起始位置
* @param length 能够使用的数组长度
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
} /**
* 扫描到元素节点结束标志时调用
*
* 应该是最重要的一个方法。需要判断节点名作相应的数据解析。
* @param localName 节点名字
* @param qName 含限定符的节点名字
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
} /**
* 扫描文档结束后调用
*
* 如果有些资源需要释放的话,就在这里做好了。
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
} }

API解释

实例

需要解析的persons.xml文件内容如下:

 <?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="1" group="1">
<name>张三</name>
<age>24</age>
</person>
<person id="2" group="2">
<name>李四</name>
<age>25</age>
</person>
<person id="3" group="1">
<name>王五</name>
<age>26</age>
</person>
</persons>

定义Person实体类:

/**
* Created by Shane on 2015/4/24.
*/
public class Person {
private int id;
private int group;
private String name;
private int age; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public int getGroup() {
return group;
} public void setGroup(int group) {
this.group = group;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
StringBuilder sb = new StringBuilder(); sb.append("name: " + name);
sb.append(", age: " + age);
sb.append(", id: " + id);
sb.append(", group: " + group); return sb.toString();
}
}

Person.java

定义用于解析XML文件的解析器PersonSAXHandler 类如下:

/**
* Created by Shane on 2015/4/24.
*/
public class PersonSAXHandler extends DefaultHandler{ private static final String TAG_PERSON = "person";
private static final String TAG_NAME = "name";
private static final String TAG_AGE = "age"; private List<Person> persons;
private Person person; private StringBuffer stringBuffer; public List<Person> getPersons() {
return persons;
} @Override
public void startDocument() throws SAXException {
super.startDocument(); persons = new ArrayList<>();
stringBuffer = new StringBuffer();
} @Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes); if (localName.equals(TAG_PERSON)) {
person = new Person();
person.setId(Integer.parseInt(attributes.getValue(0)));
person.setGroup(Integer.parseInt(attributes.getValue(1)));
}
stringBuffer.setLength(0); // start a new string buffer.
} @Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length); stringBuffer.append(ch, start, length);
} @Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName); if (localName.equals(TAG_PERSON)) {
persons.add(person);
} else if (localName.equals(TAG_NAME)) {
person.setName(stringBuffer.toString().trim());
} else if (localName.equals(TAG_AGE)) {
person.setAge(Integer.parseInt(stringBuffer.toString().trim()));
} } @Override
public void endDocument() throws SAXException {
super.endDocument();
}
}

包装上述PersonSAXHandler类,定义PersonSAXParser类进行解析:

/**
* Created by Shane on 2015/4/24.
*/
public class PersonSAXParser implements PersonParser{ @Override
public List<Person> parse(InputStream inputStream) {
List<Person> persons = new ArrayList<>();
try {
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
PersonSAXHandler personSAXHandler = new PersonSAXHandler();
saxParser.parse(inputStream, personSAXHandler);
persons = personSAXHandler.getPersons();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {}
}
}
return persons;
}
}

PersonParser接口定义如下:

/**
* Created by Shane on 2015/4/24.
*/
public interface PersonParser {
public List<Person> parse(InputStream inputStream);
}

Android解析XML之SAX解析器的更多相关文章

  1. android基础---->XMl数据的解析

    在网络上传输数据时最常用的格式有两种,XML和JSON,下面首先学一下如何解析XML格式的数据,JSON的解析可以参见我的博客(android基础---->JSON数据的解析).解析XML 格式 ...

  2. 一起学Android之Xml与Json解析

    概述 在网络中,数据交互通常是以XML和Json的格式进行,所以对这两种格式的数据进行解析,是Android开发中的必备功能,本文以一个简单的小例子,简述Android开发中Xml和Json解析的常用 ...

  3. JAVA解析XML之SAX方式

    JAVA解析XML之SAX方式 SAX解析xml步骤 通过SAXParseFactory的静态newInstance()方法获取SAXParserFactory实例factory 通过SAXParse ...

  4. xml解析中的sax解析

    title: xml解析中的sax解析 tags: grammar_cjkRuby: true --- SAXPasser 类: parser(File file, DefaultHandler ha ...

  5. sax技术解析xml下jaxp解析器详细代码

    *解析xml的两种技术dom和sax dom:根据xml的层级结构在内存中分配一个树形结构,把xml标签,属性,文本封装成对象. sax方式:事件驱动,边读边解析. 在javax.xml.parser ...

  6. 使用jaxp对比xml进行SAX解析

    package cn.itcast.sax; import java.io.IOException; import javax.xml.parsers.ParserConfigurationExcep ...

  7. python 解析xml 文件: SAX方式

    环境 python:3.4.4 准备xml文件 首先新建一个xml文件,countries.xml.内容是在python官网上看到的. <?xml version="1.0" ...

  8. XML之SAX解析模型

    DOM解析会把整个XML文件全部映射成Document里的树形结构,当遇到比较大的文件时,它的内存占用很大,查找很慢 SAX就是针对这种情况出现的解决方案,SAX解析器会从XML文件的起始位置起进行解 ...

  9. [转载] python 解析xml 文件: SAX方式

    环境 python:3.4.4 准备xml文件 首先新建一个xml文件,countries.xml.内容是在python官网上看到的. <?xml version="1.0" ...

随机推荐

  1. 14.2-ELK 经典用法—企业自定义日志收集切割和mysql模块

    本文收录在Linux运维企业架构实战系列 一.收集切割公司自定义的日志 很多公司的日志并不是和服务默认的日志格式一致,因此,就需要我们来进行切割了. 1.需切割的日志示例 2018-02-24 11: ...

  2. 项目10.2-企业级自动化运维工具---puppet详解

    1.认识puppet 1.1 引入 puppet是什么,咱们先不用专业的名词解释它,咱们先描述一些工作场景,看明白这些工作场景,自然会知道puppet是什么. (1)场景一: 管理员想要在100台服务 ...

  3. flock文件锁

    linux中的定时任务crontab会定时执行一些脚本,但是脚本的时间往往无法控制,当脚本的执行时间过长,可能会导致上一次任务的脚本还没执行完,下一次任务的脚本又开始执行的问题.这种情况下会出现一些并 ...

  4. 802. Find Eventual Safe States

    https://leetcode.com/problems/find-eventual-safe-states/description/ class Solution { public: vector ...

  5. Bubblesort冒泡算法

    最简单的算法,大家都知道两层for循环,中间加一个过渡用来交换数据 小例子: package com.neuedu.algorithm;//算法 public class Bubblesort { / ...

  6. secureCRT中vim行号下划线问题

    在vim中发现开启显示行号(set number)或语法高亮(syntax on)时,发现文档中很多地方都有下划线,对视觉产生极大干扰.开始还以为是vim的某个配置造成的,后来发现真正的元凶是secu ...

  7. (JAVA指针),对象引用问题

    引出指针 从表面上看JAVA是没有指针的,或者是说,弱化了指针.但是指针在JAVA中还是真真切切存在的.在Java中我们称之为引用. String a;//引用为空 String a  = new S ...

  8. Go语言之反射(二)

    反射的值对象 反射不仅可以获取值的类型信息,还可以动态地获取或者设置变量的值.Go语言中使用reflect.Value获取和设置变量的值. 使用反射值对象包装任意值 Go语言中,使用reflect.V ...

  9. IOS开发---菜鸟学习之路--(七)-自定义UITableViewCell

    本篇将介绍如何自定义 UITableViewCell 首先选择新建文件 可以直接使用快捷键 COMMAND+n打开新建页面,然后选Objective-C class 然后选择继承之UITableVie ...

  10. 【Palindrome Partitioning】cpp

    题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...