Android XML数据解析
XML:可扩展标记语言。一般用于数据存储,SharedPreference就是使用xml文件保存信息的,SQLite底层也是xml文件,在网络方面通常作为信息的载体,把数据包装成xml来传递。
XML解析方式:SAX、DOM、PULL。
SAX解析XML数据
SAX解析速度快,占用内存少,非常适合Android等移动设备。SAX解析采用的是事件驱动,不需要解析整个文档,而是在解析过程中,判断读到的字符是否符合xml语法的某个部分(文档开始、结束,标签开始、结束),符合则出触发事件(回调方法),这些方法定义在ContentHandler接口中,为便于使用Android提供了一个DefaultHandler帮助类,只要继承这个类,重写相应的方法即可。
重写的方法:
startDocument():文档开始时触发,做初始化工作。
endDocument():文档结束时触发,完成善后工作。
startElement():元素开始时触发。
endElement():元素结束时触发。
characters(ch,start,length):处理在xml中读到的内容,ch存放文件内容、start和length读到内容在数组中的起始位置和长度。使用new String(ch,start,length)可以获取内容。
核心代码
public class SaxHelper extends DefaultHandler {
private Person person;
private ArrayList<Person> persons;
//当前解析的元素标签
private String tagName = null;
/**
* 当读取到文档开始标志是触发,通常在这里完成一些初始化操作
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
this.persons = new ArrayList<Person>();
Log.i("SAX", "读取到文档头,开始解析xml");
}
/**
* 读到一个开始标签时调用,第二个参数为标签名,最后一个参数为属性数组
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals("person")){
person = new Person();
person.setId(Integer.parseInt(attributes.getValue("id")));
Log.i("SAX", "开始处理person元素~");
}
this.tagName = localName;
}
/**
* 读到到内容,第一个参数为字符串内容,后面依次为起始位置与长度
* @param ch
* @param start
* @param length
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//判断当前标签是否有效
if (this.tagName != null){
String data = new String(ch, start, length);
//读取标签中的内容
if (this.tagName.equals("name")){
this.person.setName(data);
Log.i("SAX", "处理name元素内容");
}else if (this.tagName.equals("age")){
this.person.setAge(Integer.parseInt(data));
Log.i("SAX", "处理age元素内容");
}
}
}
/**
* 处理元素结束时触发,这里将对象添加到结合中
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (localName.equals("person")){
this.persons.add(person);
person = null;
Log.i("SAX", "处理person元素结束~");
}
this.tagName = null;
}
/**
* 读取到文档结尾时触发,
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
Log.i("SAX", "读取到文档尾,xml解析结束");
}
//获取persons集合
public ArrayList<Person> getPersons(){
return persons;
}
}
在MainActivity.java中写上这样一个方法,然后要解析XML的时候调用下
private ArrayList<Person> readxmlForSAX() throws Exception {
//获取文件资源建立输入流对象
InputStream is = getAssets().open("person1.xml");
//①创建XML解析处理器
SaxHelper ss = new SaxHelper();
//②得到SAX解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//③创建SAX解析器
SAXParser parser = factory.newSAXParser();
//④将xml解析处理器分配给解析器,对文档进行解析,将事件发送给处理器
parser.parse(is, ss);
is.close();
return ss.getPersons();
}
DOM解析XML数据
DOM解析xml文件时,会将文件中所有内容以文档树的形式存放到内存中,然后使用DOM API遍历、检索数据。DOM解析比较直观,编码较为简单,但是内存消耗大。
DOM中的api:
DocumentBuilderFactory()(解析工厂类):创建:DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder(解析器类):通过解析工厂来获得:DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
Document(文档树模型):将要解析的xml文件读入DOM解析器Document doc = dbBuilder.parse(context.getAssets().open("person2.xml"));
NodeList(结点列表类):含有方法:item(index)、getLength()
Node()(结点类):DOM中最基本的对象,抽象结点,一般使用它的子对象,Element、Attr、Text等
Element()(元素类):方法:getAttribute()、getTagName()
Attr()(属性类):某个元素的属性。
核心代码
public class DomHelper {
public static ArrayList<Person> queryXML(Context mContent){
ArrayList<Person> persons = new ArrayList<Person>();
try {
//①获得DOM解析器的工厂示例:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
//②从Dom工厂中获得dom解析器
DocumentBuilder builder = dbFactory.newDocumentBuilder();
//③把要解析的xml文件读入Dom解析器
Document document = builder.parse(mContent.getAssets().open("person2.xml"));
System.out.println("处理该文档的DomImplemention对象=" + document.getImplementation());
//④得到文档中名称为person的元素的结点列表
NodeList nodeList = document.getElementsByTagName("person");
//⑤遍历该集合,显示集合中的元素以及子元素的名字
for (int i = 0; i < nodeList.getLength(); i ++){
//先从Person元素开始解析
Element personElement = (Element)nodeList.item(i);
Person person = new Person();
person.setId(Integer.valueOf(personElement.getAttribute("id")));
//获取person下的name和age的Note集合
NodeList childList = personElement.getChildNodes();
for (int j = 0; j < childList.getLength(); j ++){
Node childNode = childList.item(j);
//判断子note类型是否为元素Note
if (childNode.getNodeType() == Node.ELEMENT_NODE){
Element childElement = (Element)childNode;
if ("name".equals(childElement.getNodeName())){
person.setName(childElement.getFirstChild().getNodeValue());
}else if("age".equals(childElement.getNodeName())){
person.setAge(Integer.valueOf(childElement.getFirstChild().getNodeValue()));
}
}
}
persons.add(person);
}
} catch (Exception e) {
e.printStackTrace();
}
return persons;
}
PULL解析XML数据
Android中内置了PULL解析器,PULL解析同样采用事件驱动,编码简单,只需处理开始和结束事件,通常使用switch语句,根据事件的类型,匹配不同的处理方法。
事件类型:START_DOCUMENT、START_TAG、TEXT、END_TAG、END_DOCUMENT。
PULL解析返回的是数字,需要我们自己获取产生的事件,然后做相应的操作。
PULL解析xml文件流程:
public static ArrayList<Person> getPersons(InputStream xml) throws Exception{
ArrayList<Person> persons = null;
Person person = null;
// 1、创建一个xml解析的工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//2、获得xml解析类的引用
XmlPullParser parser = factory.newPullParser();
parser.setInput(xml, "UTF-8");
//3、获得事件的类型
int eventType = parser.getEventType();
//4、用switch对不同的事件进行不同的处理
while (eventType != XmlPullParser.END_DOCUMENT){
switch (eventType){
case XmlPullParser.START_DOCUMENT:{
persons = new ArrayList<Person>();
break;
}
case XmlPullParser.START_TAG:{
if ("person".equals(parser.getName())){
person = new Person();
// 取出属性值
int id = Integer.parseInt(parser.getAttributeValue(0));
person.setId(id);
}else if("name".equals(parser.getName())){
// 获取该节点的内容
String name = parser.nextText();
person.setName(name);
}else if("age".equals(parser.getName())){
int age = Integer.parseInt(parser.nextText());
person.setAge(age);
}
break;
}
case XmlPullParser.END_TAG:{
if ("person".equals(parser.getName())){
persons.add(person);
person = null;
}
break;
}
}
eventType = parser.next();
}
return persons;
}
PULL生成xml文件流程
public static void save(List<Person> persons, OutputStream outputStream) throws Exception{
//创建XmlSerializer实例
XmlSerializer serializer = Xml.newSerializer();
//为XmlSerializer设置输入流和编码格式
serializer.setOutput(outputStream, "UTF-8");
//设置xml的编码格式
serializer.startDocument("UTF-8", true);
//设置根元素
serializer.startTag(null, "persons");
//遍历元素依次写入标签和属性
for (Person person: persons) {
serializer.startTag(null, "person");
serializer.attribute(null, "id", person.getId() + "");
serializer.startTag(null, "name");
serializer.text(person.getName());
serializer.endTag(null, "name");
serializer.startTag(null, "age");
serializer.text(person.getAge() + "");
serializer.endTag(null, "age");
//设置完结元素标签
serializer.endTag(null, "person");
}
serializer.endTag(null, "persons");
//结束文档
serializer.endDocument();
//flush()刷新,将数据写入文件,关闭输出流
outputStream.flush();
outputStream.close();
}
参考文献:http://www.jianshu.com/p/2fe796ca638c
Android XML数据解析的更多相关文章
- 二、Android XML数据解析
XML,可扩展标记语言.可以用来存储数据,可以看做是一个小型的数据库,SharedPreference就是使用XML文件存储数据的,SQLite底层也是一个XML文件,而在网络应用方面,通常作为信息的 ...
- xml数据解析
xml数据解析 在iPhone开发中,XML的解析有很多选择,iOS SDK提供了NSXMLParser和libxml2两个类库,另外还有很多第三方类库可选,例如TBXML.TouchXML.Kiss ...
- iOS - XML 数据解析
前言 @interface NSXMLParser : NSObject public class NSXMLParser : NSObject 1.XML 数据 XML(Extensible Mar ...
- xml数据解析调研
XML数据解析http://www.tuicool.com/articles/Nraau2(必用) http://www.cnblogs.com/pengyingh/articles/2342699. ...
- iOS开发——网络Swift篇&JSON与XML数据解析
JSON与XML数据解析 JSON数据解析(内置NSJSONSerialization与第三方JSONKit) 一,使用自带的NSJSONSerialization 苹果从IOS5.0后推出了SD ...
- iOS开发网络篇之Web Service和XML数据解析
郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下 ...
- 关于C#对Xml数据解析
首先进行简单说明Xml 与Html 和 XAML数据标签的差别. 1.Xml属于数据文本, 被设计为传输和存储数据,其焦点是数据的内容.它与json格式数据相似,可作为服务数据传输类型. 其中XML ...
- Android 之XML数据解析(2)—— SAX解析
(以下文章基本照抄郭霖大神的<第一行代码>) 在Android之 解析XML文件(1)—— Pull解析 中我们讲了Pull方式解析XML文件.今天讲另外一种方式,SAX解析XML文件. ...
- iOS学习笔记(九)——xml数据解析
在iPhone开发中,XML的解析有很多选择,iOS SDK提供了NSXMLParser和libxml2两个类库,另外还有很多第三方类库可选,例如TBXML.TouchXML.KissXML.Tiny ...
随机推荐
- Mininet实验 测量路径损耗率
参照:基于Mininet测量路径的损耗率 在SDN环境中,可以利用控制器来测量特定路径的损耗率,在本实验中,基于Mininet脚本,设置特定的交换机间的路径损耗速率,然后编写POX脚本,实现对路径的损 ...
- 机器学习-ID3决策树算法(附matlab/octave代码)
ID3决策树算法是基于信息增益来构建的,信息增益可以由训练集的信息熵算得,这里举一个简单的例子 data=[心情好 天气好 出门 心情好 天气不好 出门 心情不好 天气好 出门 心情不好 天气不好 ...
- UOJ #266 【清华集训2016】 Alice和Bob又在玩游戏
题目链接:Alice和Bob又在玩游戏 这道题就是一个很显然的公平游戏. 首先\(O(n^2)\)的算法非常好写.暴力枚举每个后继计算\(mex\)即可.注意计算后继的时候可以直接从父亲转移过来,没必 ...
- hdu 3792 Twin Prime Conjecture 前缀和+欧拉打表
Twin Prime Conjecture Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- nodejs项目的model操作mongo
想想以前学习hibernate的时候,学习各种表和表之间的映射关系等一对多,多对一,多对多,后来到了工作中,勇哥告诉我, 那时在学习的时候,公司中都直接用外键关联. 这里我们学习下,如何在Nodejs ...
- 根据rowid查找所属的对象号、文件号、块号、行号-还是简单一点吧
select rowid, dbms_rowid.rowid_object(rowid) obj#, dbms_rowid.rowid_block_number(rowid) ...
- Gitlab项目用ssh克隆
Gitlab项目用ssh克隆 1. 新建一个文件夹并用git bash here 打开 2. 在git bash here 输入命令行 ssh-keygen –t rsa –C“邮箱名” 3. ...
- 素数对猜想之python3实现
题目 让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数.显然有d1=1,且对于n>1有dn是偶数.“素数对猜想”认为“存在无穷多对相邻且差为 ...
- jsr303 参考表
下面是主要的验证注解及说明: 注解 适用的数据类型 说明 @AssertFalse Boolean, boolean 验证注解的元素值是false @AssertTrue Boolean, boole ...
- SharePoint Development - Custom List using Visual Studio 2010 based SharePoint 2010
博客地址 http://blog.csdn.net/foxdave 之前两次我们定义了内容类型和字段,我们现在用它们为这一讲服务--创建一个自定义列表. 打开Visual Studio,打开之前的工程 ...