热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android利用SAX对XML进行增删改查操作详解

在项目中会遇到对于XML的增删改查,下面这篇文章主要给大家介绍了关于Android利用SAX对XML进行增删改查操作的相关资料,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧。

前言

解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析。

DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了。

  优点:整个文档读入内存,方便操作:支持修改、删除和重现排列等多种功能。

  缺点:将整个文档读入内存中,保留了过多的不需要的节点,浪费内存和空间。

  使用场合:一旦读入文档,还需要多次对文档进行操作,并且在硬件资源充足的情况下(内存,CPU)。

为了解决DOM解析存在的问题,就出现了SAX解析。其特点为:

  优点:不用实现调入整个文档,占用资源少。尤其在嵌入式环境中,如android,极力推荐使用SAX解析。

  缺点:不像DOM解析一样将文档长期驻留在内存中,数据不是持久的。如果事件过后没有保存数据,数据就会丢失。

  使用场合:机器有性能限制。

本文将给大家详细介绍关于Android利用SAX对XML增删改查的相关内容,分享出来供大家参考学习价值,下面话不多说了,来一起看看详细的介绍吧。

1.概述

SAX是一中事件驱动类型的XML解析方式。说白了,就是通过复写一个Default类去告知,解析的结果。SAX并不会想DOM那样把整个的XML加载到内存中,而它会像IO流那样,一个一个标签地去解析。

简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

为了方便说明,先约定好一个XML如下:

<&#63;xml version="1.0" encoding="UTF-8"&#63;>

 
  zhangsan
  21
 

2.基本读取(查)

代码如下

SAXParserFactory factory = SAXParserFactory.newInstance();//创建SAX解析工厂
SAXParser saxParser;
try {
 File file = new File(xmlFilePath);
 InputStream inputStream = new FileInputStream(file);//得到输入流
 saxParser = factory.newSAXParser();//创建解析器
 saxParser.parse(inputStream,new DefaultHandler(){//开始解析
  //文档开始标记
  @Override
  public void startDocument() throws SAXException {
   super.startDocument();
   Log.i("loadWithSax","startDocument");
  }
  //文档结束标记
  @Override
  public void endDocument() throws SAXException {
   super.endDocument();
   FileUtils.closeIO(inputStream);
   Log.i("loadWithSax","endDocument");
  }
  //解析到标签
  @Override
  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SA
   super.startElement(uri, localName, qName, attributes);
   Log.i("loadWithSax","startElement"+",uri:"+uri+",localName:"+localName+",qName:"+qName);
   if (attributes!=null) {
    for (int i = 0; i "的位置。length就是">"到下一个"<"的长度。
   * 
   *  michael
   * 
   * 执行namesList节点时,因为没有文本,
   * 不会执行到该方法。
   */
  @Override
  public void characters(char[] ch, int start, int length) throws SAXException {
   super.characters(ch, start, length);
   Log.i("loadWithSax","characters"+",start:"+start+",length:"+length);
   for (int i = 0; i 
  • 传入:DefaultHandler的实体,通过复写其中的方法,查询到文档,标签的内容:
  • startDocument 和 endDocument是扫描文档的开始和结束
  • startElement,是解析到了标签,localName就是标签的名称,如本文所示例的,当解析到第一个人名的时候,

 zhangsan
 21

解析到回调:startElement,标签内的参数是Attributes attributes,一个for循环就可以遍历读取。

characters,解析到标签的内容时候回调,接着上面例子,解析,回调startElement,然后不会回调此方法,因为内容不是文本,而是包含了标签,所以,解析到其子标签:zhangsan的时候,又会先回调回调startElement,然后,才回调characters,告诉你,这个标签里面有文本内容!参数说明如下:

  • char[] : 内容字符数组里面。如:zhangsan,char[]就是:{'z','h','a','n','g','s','a','n'}
  • start :0,文本的开始
  • length :文本的长度。
  • endElement,标签结束。

使用上面的代码,得到的部分log如下:

I/loadWithSax: startDocument
I/loadWithSax: startElement,uri:,localName:persons,qName:persons
I/loadWithSax: characters,start:0,length:1
I/loadWithSax: char:
    ,ASCII:10
I/loadWithSax: characters,start:0,length:1
I/loadWithSax: char: ,ASCII:9
I/loadWithSax: startElement,uri:,localName:person,qName:person
I/loadWithSax: id,1,CDATA
I/loadWithSax: key,33,CDATA
I/loadWithSax: type,type,CDATA
I/loadWithSax: characters,start:0,length:1
I/loadWithSax: char:
    ,ASCII:10
I/loadWithSax: characters,start:0,length:2
I/loadWithSax: char: ,ASCII:9
I/loadWithSax: char: ,ASCII:9
I/loadWithSax: startElement,uri:,localName:name,qName:name
I/loadWithSax: characters,start:0,length:8
I/loadWithSax: char:z,ASCII:122
I/loadWithSax: char:h,ASCII:104
I/loadWithSax: char:a,ASCII:97
I/loadWithSax: char:n,ASCII:110
I/loadWithSax: char:g,ASCII:103
I/loadWithSax: char:s,ASCII:115
I/loadWithSax: char:a,ASCII:97
I/loadWithSax: char:n,ASCII:110
I/loadWithSax: endElement,uri:,localName:name,qName:name

startDocument,开始解析xml

解析到第一个标签的开始:

然后解析到了内容???characters?按照我上面的分析,标签内没有文字内容,应该不会回调。其实,这里回调的是换行符。log中打出了ASCII码,10就是换行。然后,还有一个tab符。

然后就是里面的,有三个参数:id,key,type,巴拉巴拉。。。

3.保存

sax的保存有点麻烦。具体是XmlSerializer的使用。

初始化一个XmlSerializer:

StringWriter stringWriter = new StringWriter();
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlSerializer xmlSerializer = factory.newSerializer();
xmlSerializer.setOutput(stringWriter);

声明文档的开始和结束:

xmlSerializer.startDocument("utf-8", false);//false,是声明:standalone的值。
xmlSerializer.endDocument();

标签的开始结束,和写入内容:

xmlSerializer.startTag(null, "name");//开始,第一个参数是namespace,命名空间。
xmlSerializer.text(person.name);//写入内容
xmlSerializer.endTag(null, "name");

实战:

假如,我们需要构建如下的XML:

<&#63;xml version='1.0' encoding='utf-8' standalOne='yes' &#63;>

 
  zhangsan
  21
 
 
  lisi
  12
 
 
  wangwu
  23
 

首先你得定义好一个Bean类,Person:

public class Person {
 public int id = -1;
 public String key = null;
 public String type = null;
 public String name;
 public int age;
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
}

然后开撸:最后的stringWriter就是你想要的数据,注意就是,一些换行和tab符。

StringWriter stringWriter = new StringWriter();
try {
  XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
  XmlSerializer xmlSerializer = factory.newSerializer();
  xmlSerializer.setOutput(stringWriter);
  //制造假数据:
  ArrayList persOnArrayList= new ArrayList<>();
  Person person1 = new Person("zhangsan",21);
  person1.id=1;
  person1.key="33";
  person1.type="type";
  Person person2 = new Person("lisi",12);
  Person person3 = new Person("wangwu",23);
  personArrayList.add(person1);
  personArrayList.add(person2);
  personArrayList.add(person3);
  //star document
  xmlSerializer.startDocument("utf-8", true);
  xmlSerializer.text("\n");
  xmlSerializer.startTag(null, "persons");
  for(Person person:personArrayList){
    //star tag
    xmlSerializer.text("\n");
    xmlSerializer.text("\t");
    xmlSerializer.startTag(null, "person");
    //添加参数
    if (person.id!=-1) {
      xmlSerializer.attribute(null,"id",String.valueOf(person.id));
    }
    if (person.key!=null) {
      xmlSerializer.attribute(null,"key",person.key);
    }
    if (person.type!=null) {
      xmlSerializer.attribute(null,"type",person.type);
    }
    //添加内容:name
    xmlSerializer.text("\n");
    xmlSerializer.text("\t");
    xmlSerializer.text("\t");
    xmlSerializer.startTag(null, "name");
    xmlSerializer.text(person.name);
    xmlSerializer.endTag(null, "name");
    //添加内容:age
    xmlSerializer.text("\n");
    xmlSerializer.text("\t");
    xmlSerializer.text("\t");
    xmlSerializer.startTag(null, "age");
    xmlSerializer.text(String.valueOf(person.age));
    xmlSerializer.endTag(null, "age");
    //end tag
    xmlSerializer.text("\n");
    xmlSerializer.text("\t");
    xmlSerializer.endTag(null, "person");
  }
  //end document
  xmlSerializer.text("\n");
  xmlSerializer.endTag(null, "persons");
  xmlSerializer.endDocument();
} catch (Exception e) {
  e.printStackTrace();
}

XmlSerializer的初始化需要传入一个write对象,你可以传入一个FileWrite,写到文件里面:

// 创建文件对象
File fileText = new File(saveFilePath);
// 向文件写入对象写入信息
FileWriter stringWriter;
xmlSerializer.setOutput(stringWriter);
//...同上
//记得close
if (stringWriter != null) {
  stringWriter.close();
}

4.增删

增加和删除,那么你需要先对XML进行映射,映射成一堆的Bean,然后增加删除Bean,再保存即可。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。


推荐阅读
  • Android 九宫格布局详解及实现:人人网应用示例
    本文深入探讨了人人网Android应用中独特的九宫格布局设计,解析其背后的GridView实现原理,并提供详细的代码示例。这种布局方式不仅美观大方,而且在现代Android应用中较为少见,值得开发者借鉴。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 本文详细介绍如何使用arm-eabi-gdb调试Android平台上的C/C++程序。通过具体步骤和实用技巧,帮助开发者更高效地进行调试工作。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 本文将详细介绍如何使用剪映应用中的镜像功能,帮助用户轻松实现视频的镜像效果。通过简单的步骤,您可以快速掌握这一实用技巧。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
author-avatar
许晓慧
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有