Android SAX解析XML文档 -- Android 学习之路
来源:互联网 发布:数据库考点总结 编辑:程序博客网 时间:2024/05/03 10:26
SAX解析XML
最近用到了XML数据 ,今天分享一下我对SAX的理解
- 原理
- 实例
- 自定义Handler 继承DefaultHandler
- Handler执行顺序各方法参数讲解
- SaxParse的创建
- 设置解析内容 开始解析
原理
sax 是基于事件驱动。那么什么是事件驱动呢(请自行百度)简单点说 就是触发一个事件 去执行某些操作;
sax在解析XML时 是边读取边解析,不会将整个文档加载到内存中。而是读到一个元素解析一个元素,和上下的元素是关联不上的,占用内存较小。这也是非常适合Android这种内存较小的嵌入式设备内存的原因;
sax在读取文档的时候激活一系列的事件并执行一些操作。
在开始读取文档的时候触发 startDocument() ;
读取到一个元素触发 startElement();
读取文本 触发characters(); ps:即使是读取到换行符也会触发
元素读取完毕 触发 endElement();
读取完整个文档触发 endDocument();
上述事件 基本就把xml文档读取完毕了,这些方法在DefaultHandle中已经封装好了,我们做的就是重写这些方法就可以了
贴代码
student XML文件
<?xml version="1.0" encoding="utf-8"?><Students> <Student id="0"> <name>张三</name> <clazz>13班</clazz> <age>17</age> </Student></Students>
创建 StudentHandler 继承自 DefaultHandler
package com.skymxc.demo.parsexml;import android.text.TextUtils;import android.util.Log;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import java.util.ArrayList;import java.util.List;/** * Created by sky-mxc */public class StudentHandler extends DefaultHandler { private List<Student> students; private Student student; private String tag; //记录读取到的元素的名字 @Override public void startDocument() throws SAXException { Log.e("Tag","=======startDocument()========"); students = new ArrayList<>(); } @Override public void endDocument() throws SAXException { super.endDocument(); Log.e("Tag","=======endDocument()========"); } /** * * @param uri 明明空间的uri * @param localName 不带前缀的元素名字 * @param qName 带有前缀的元素名 * @param attributes 属性 * @throws SAXException */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { Log.e("Tag","==========startElement()==========="+localName); Log.e("Tag","===startElement():uri======"+uri); Log.e("Tag","===startElement():localName======"+localName); Log.e("Tag","===startElement():qName======"+qName); switch (localName){ case "Student": //student元素 student = new Student(); int id = Integer.parseInt(attributes.getValue("id")); //获取到属性id的值 student.setId(id); break; default: tag=localName;//除了 student元素 其他元素都要读取文本 characters()无法获取元素名字 break; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); Log.e("Tag","==========endElement()==========="+localName); switch (localName){ case "Student": students.add(student); break; } } @Override public void characters(char[] ch, int start, int length) throws SAXException { Log.e("Tag","==========characters()==========="); Log.e("Tag","======start:"+start); Log.e("Tag","======length:"+length); //将字符转为字符串 String text = new String(ch,start,length).trim(); Log.e("Tag","====当前元素:"+tag+"===文本值:"+text); //排除无效字符 会读取到一些换行符 if (TextUtils.isEmpty(text)) return; if (student == null) return; switch (tag){ case "name": student.setName(text); break; case "age": int age = Integer.parseInt(text); student.setAge(age); break; case "clazz": student.setClazz(text); break; } } public List<Student> getStudents() { return students; }}
Handler中的执行过程解析 读取过程如下,可以看出 就算根节点没有文本也触发了characters() 因为会读取换行符 所以慎重处理
E/Tag: =======startDocument()========E/Tag: ==========startElement()===========StudentsE/Tag: ==========characters()===========E/Tag: ==========characters()===========E/Tag: ==========startElement()===========StudentE/Tag: ==========characters()===========E/Tag: ==========characters()===========E/Tag: ==========startElement()===========nameE/Tag: ==========characters()===========E/Tag: ==========endElement()===========nameE/Tag: ==========characters()===========E/Tag: ==========characters()===========E/Tag: ==========startElement()===========clazzE/Tag: ==========characters()===========E/Tag: ==========endElement()===========clazzE/Tag: ==========characters()===========E/Tag: ==========characters()===========E/Tag: ==========startElement()===========ageE/Tag: ==========characters()===========E/Tag: ==========endElement()===========ageE/Tag: ==========characters()===========E/Tag: ==========characters()===========E/Tag: ==========endElement()===========StudentE/Tag: ==========characters()===========E/Tag: ==========endElement()===========StudentsE/Tag: =======endDocument()========
startElement() 参数如下 xml 文件中并没有定义 命名空间 和任何前缀
uri :为空
qName :也是元素的名字并没有带有前缀
localName: 当前元素的名字
E/Tag: ===startElement():uri======E/Tag: ===startElement():localName======StudentE/Tag: ===startElement():qName======StudentE/Tag: ==========characters()===========
characters()参数如下
start :开始下标
length :长度
E/Tag: ==========characters()=========== E/Tag: ======start:0 E/Tag: ======length:3 E/Tag: ====当前元素:clazz===文本值:13班
创建SAXParse 设置解析内容
SAXParserFactory factory = SAXParserFactory.newInstance(); StudentHandler handler = new StudentHandler(); try { SAXParser parser = factory.newSAXParser(); parser.parse(getAssets().open("students.xml"),handler); Log.e("Tag","===Size:"+handler.getStudents().size()); for (Student stu :handler.getStudents()){ Log.e("Tag","==Name:"+stu.getName()+"===Age:"+stu.getAge()+"====Clazz:"+stu.getClazz()+"==id:"+stu.getId()); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
读取结果
E/Tag: ==Name:张三===Age:17====Clazz:13班==id:0
对于SAX的理解就这些了
为什么只有深夜 才有感觉呢,唉…..发愁github地址 :https://github.com/sky-mxc/AndroidDemo/tree/master/parsexml
- Android SAX解析XML文档 -- Android 学习之路
- android开发之sax解析xml文档
- Android Sax解析XML文档
- Android学习笔记--解析XML之SAX
- Android学习-Sax解析XML
- Android之SAX解析XML
- Android 解析XML 之SAX
- Android之SAX解析XML
- Android之SAX解析XML
- android xml解析之SAX
- Android之SAX解析XML
- Android xml解析之Sax
- Android之SAX解析XML
- Android SAX,DOM,PULL解析XML文档
- android的sax解析XML文档
- Android使用SAX解析XML文档
- android中用SAX方式解析XML文档
- Android学习笔记之XML解析(SAX)
- 《OpenGL ES 2.0 Programming Guide》第12章“最简单的ReadPixels并保存为BMP”示例代码【C语言版】
- Codeforces Round #369 (Div. 2) A~D
- CSU1810(2016年湖南省第十二届大学生计算机程序设计竞赛 - H)
- 分布式系统下的纠删码(二) -- Locally Repairable Codes (LRC)
- 笔记 AndroidManifest.xml文件详解
- Android SAX解析XML文档 -- Android 学习之路
- 前端代码规范( HTML篇)
- HTML表格标签
- 操作系统基础(一)
- Git3.创建版本库(Git仓库)&提交更新到仓库
- 三、Lua中的语句
- 前端代码规范化( CSS篇 )
- TIJ读书笔记06-终结清理和垃圾回收
- 【BLE-CC2640】CC2640之修改发射功率