XML作为一种业界公认的数据交换格式,在各个平台与语言之上,都有广泛使用和实现。其标准型,可靠性,安全性......毋庸置疑。在android平台上,我们要想实现数据存储和数据交换,经常会使用到xml数据格式和xml文件。

小提示:android中存储数据一般有如下几种:SharedPreferences(参数化),XML文件,sqllite数据库,网络,ContentProvider(内容提供者)等。

在android中,操作xml文件,一般有几种方式:SAX操作,Pull操作,DOM操作等。其中DOM的方式,可能是大家最熟悉的,也是符合W3C标准的。

1)

在java平台中,有诸如DOM4J这样优秀的开源包,极大程度的方便大家使用DOM标准来操作XML文件。在javascript中,不同的浏览器解析引擎,对DOM的解析和操作也略有差异(不过这不是本章介绍的重点)。而DOM的方式,也有其缺点。通常一次性加载xml文件,再使用DOM的 api去进行解析,这样很大程度的消耗内存,对性能会有一定影响。而我们的android手机,虽然配置在不断的升级,但是内存方面,暂时还无法与传统的PC去媲美。所以,在android上面,不太推荐使用DOM的方式来解析和操作XML。

  1. package cn.itcast.service;
  2. import java.io.InputStream;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import javax.xml.parsers.DocumentBuilder;
  6. import javax.xml.parsers.DocumentBuilderFactory;
  7. import org.w3c.dom.Document;
  8. import org.w3c.dom.Element;
  9. import org.w3c.dom.Node;
  10. import org.w3c.dom.NodeList;
  11. import cn.itcast.model.Person;
  12. public class DomPersonService {
  13. public List<Person> getPersons(InputStream stream) throws Throwable
  14. {
  15. List<Person> list =new ArrayList<Person>();
  16. DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
  17. DocumentBuilder builder =factory.newDocumentBuilder();
  18. Document dom = builder.parse(stream);//解析完成,并以dom树的方式存放在内存中。比较消耗性能
  19. //开始使用dom的api去解析
  20. Element root = dom.getDocumentElement();//根元素
  21. NodeList personNodes = root.getElementsByTagName("person");//返回所有的person元素节点
  22. //开始遍历啦
  23. for(int i=0;i<personNodes.getLength();i++)
  24. {
  25. Person person =new Person();
  26. Element personElement =(Element)personNodes.item(i);
  27. person.setId(new Integer( personElement.getAttribute("id")));//将person元素节点的属性节点id的值,赋给person对象
  28. NodeList personChildrenNodes =personElement.getChildNodes();//获取person节点的所有子节点
  29. //遍历所有子节点
  30. for(int j=0;j<personChildrenNodes.getLength();j++)
  31. {
  32. //判断子节点是否是元素节点(如果是文本节点,可能是空白文本,不处理)
  33. if(personChildrenNodes.item(j).getNodeType()==Node.ELEMENT_NODE)
  34. {
  35. //子节点--元素节点
  36. Element childNode =(Element)personChildrenNodes.item(j);
  37. if("name".equals(childNode.getNodeName()))
  38. {
  39. //如果子节点的名称是“name”.将子元素节点的第一个子节点的值赋给person对象
  40. person.setName(childNode.getFirstChild().getNodeValue());
  41. }else if("age".equals(childNode.getNodeValue()))
  42. {
  43. person.setAge(new Integer(childNode.getFirstChild().getNodeValue()));
  44. }
  45. }
  46. }
  47. list.add(person);
  48. }
  49. return list;
  50. }
  51. }

2)

SAX(Simple API for XML),是一个使用非常广泛的XML解析标准,通常使用Handler模式来处理XML文档,这种处理模式和我们平常习惯的理解方式很不同,身边也经常有一些朋友在刚接触SAX的时候会觉得理解起来有些困难。其实SAX并不复杂,只不过是换了一种思维方式,正如它的名字所表示的,为了让我们以更简单的方式来处理XML文档,下面我们就开始吧。

  1. package cn.itcast.service;
  2. import java.io.InputStream;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import javax.xml.parsers.SAXParser;
  6. import javax.xml.parsers.SAXParserFactory;
  7. import org.xml.sax.Attributes;
  8. import org.xml.sax.SAXException;
  9. import org.xml.sax.helpers.DefaultHandler;
  10. import cn.itcast.model.Person;
  11. public class SAXPersonService {
  12. public List<Person> getPersons(InputStream inStream) throws Throwable
  13. {
  14. SAXParserFactory factory = SAXParserFactory.newInstance();//工厂模式还是单例模式?
  15. SAXParser parser =factory.newSAXParser();
  16. PersonParse personParser =new PersonParse();
  17. parser.parse(inStream, personParser);
  18. inStream.close();
  19. return personParser.getPerson();
  20. }
  21. private final class PersonParse extends DefaultHandler
  22. {
  23. private List<Person> list = null;
  24. Person person =null;
  25. private String tag=null;
  26. public List<Person> getPerson() {
  27. return list;
  28. }
  29. @Override
  30. public void startDocument() throws SAXException {
  31. list =new ArrayList<Person>();
  32. }
  33. @Override
  34. public void startElement(String uri, String localName, String qName,
  35. Attributes attributes) throws SAXException {
  36. if("person".equals(localName))
  37. {
  38. //xml元素节点开始时触发,是“person”
  39. person = new Person();
  40. person.setId(new Integer(attributes.getValue(0)));
  41. }
  42. tag =localName;//保存元素节点名称
  43. }
  44. @Override
  45. public void endElement(String uri, String localName, String qName)
  46. throws SAXException {
  47. //元素节点结束时触发,是“person”
  48. if("person".equals(localName))
  49. {
  50. list.add(person);
  51. person=null;
  52. }
  53. tag =null;//结束时,需要清空tag
  54. }
  55. @Override
  56. public void characters(char[] ch, int start, int length)
  57. throws SAXException {
  58. if(tag!=null)
  59. {
  60. String data = new String(ch,start,length);
  61. if("name".equals(tag))
  62. {
  63. person.setName(data);
  64. }else if("age".equals(tag))
  65. {
  66. person.setAge(new Integer(data));
  67. }
  68. }
  69. }
  70. }
  71. }

3)

Pull解析和Sax解析很相似,都是轻量级的解析,在Android的内核中已经嵌入了Pull,所以我们不需要再添加第三方jar包来支持Pull。Pull解析和Sax解析不一样的地方有(1)pull读取xml文件后触发相应的事件调用方法返回的是数字(2)pull可以在程序中控制想解析到哪里就可以停止解析。

  1. package cn.itcast.service;
  2. import java.io.InputStream;
  3. import java.io.Writer;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.xmlpull.v1.XmlPullParser;
  7. import org.xmlpull.v1.XmlSerializer;
  8. import android.util.Xml;
  9. import cn.itcast.model.Person;
  10. public class PullPersonService {
  11. //保存xml文件
  12. public static void saveXML(List<Person> list,Writer write)throws Throwable
  13. {
  14. XmlSerializer serializer =Xml.newSerializer();//序列化
  15. serializer.setOutput(write);//输出流
  16. serializer.startDocument("UTF-8", true);//开始文档
  17. serializer.startTag(null, "persons");
  18. //循环去添加person
  19. for (Person person : list) {
  20. serializer.startTag(null, "person");
  21. serializer.attribute(null, "id", person.getId().toString());//设置id属性及属性值
  22. serializer.startTag(null, "name");
  23. serializer.text(person.getName());//文本节点的文本值--name
  24. serializer.endTag(null, "name");
  25. serializer.startTag(null, "age");
  26. serializer.text(person.getAge().toString());//文本节点的文本值--age
  27. serializer.endTag(null, "age");
  28. serializer.endTag(null, "person");
  29. }
  30. serializer.endTag(null, "persons");
  31. serializer.endDocument();
  32. write.flush();
  33. write.close();
  34. }
  35. public List<Person> getPersons(InputStream stream) throws Throwable
  36. {
  37. List<Person> list =null;
  38. Person person =null;
  39. XmlPullParser parser =Xml.newPullParser();
  40. parser.setInput(stream,"UTF-8");
  41. int type =parser.getEventType();//产生第一个事件
  42. //只要当前事件类型不是”结束文档“,就去循环
  43. while(type!=XmlPullParser.END_DOCUMENT)
  44. {
  45. switch (type) {
  46. case XmlPullParser.START_DOCUMENT:
  47. list =  new ArrayList<Person>();
  48. break;
  49. case XmlPullParser.START_TAG:
  50. String name=parser.getName();//获取解析器当前指向的元素名称
  51. if("person".equals(name))
  52. {
  53. person =new Person();
  54. person.setId(new Integer(parser.getAttributeValue(0)));
  55. }
  56. if(person!=null)
  57. {
  58. if("name".equals(name))
  59. {
  60. person.setName(parser.nextText());//获取解析器当前指向的元素的下一个文本节点的文本值
  61. }
  62. if("age".equals(name))
  63. {
  64. person.setAge(new Integer(parser.nextText()));
  65. }
  66. }
  67. break;
  68. case XmlPullParser.END_TAG:
  69. if("person".equals(parser.getName()))
  70. {
  71. list.add(person);
  72. person=null;
  73. }
  74. break;
  75. }
  76. type=parser.next();//这句千万别忘了哦
  77. }
  78. return list;
  79. }
  80. }

下面是Model层的Person类的代码:

    1. package cn.itcast.model;
    2. public class Person {
    3. private Integer id;
    4. public Integer getId() {
    5. return id;
    6. }
    7. public void setId(Integer id) {
    8. this.id = id;
    9. }
    10. private String name;
    11. public String getName() {
    12. return name;
    13. }
    14. public void setName(String name) {
    15. this.name = name;
    16. }
    17. private Integer age;
    18. public Integer getAge() {
    19. return age;
    20. }
    21. public void setAge(Integer age) {
    22. this.age = age;
    23. }
    24. public Person()
    25. {
    26. }
    27. public Person(Integer id, String name, Integer age) {
    28. this.id = id;
    29. this.name = name;
    30. this.age = age;
    31. }
    32. @Override
    33. public String toString() {
    34. return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
    35. }
    36. }

转载自:http://blog.csdn.net/dinglang_2009/article/details/6940225

android操作XML的几种方式(转)的更多相关文章

  1. C#操作xml的3种方式

    C#操作Xml有很多种方式,这里写出个人常使用的三种方式 XmlDocument DataSet linq to xml  首先声明本次操作使用的xml文件:books.xml:内容如下 <?x ...

  2. Android处理XML的三种方式

    http://www.cnblogs.com/zhangdongzi/archive/2011/04/14/2016434.html http://blog.csdn.net/zzp16/articl ...

  3. Android开发之使用sqlite3工具操作数据库的两种方式

    使用 sqlite3 工具操作数据库的两种方式 请尊重他人的劳动成果,转载请注明出处:Android开发之使用sqlite3工具操作数据库的两种方式 http://blog.csdn.net/feng ...

  4. 简介C#读取XML的两种方式

    简介C#读取XML的两种方式 作者: 字体:[增加 减小] 类型:转载 时间:2013-03-03 在程序中访问进而操作XML文件一般有两种模型,分别是使用DOM(文档对象模型)和流模型,使用DOM的 ...

  5. JAVA解析XML的四种方式

    java解析xml文件四种方式 1.介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这 ...

  6. android 数据存储的几种方式

    总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.其中文件和数据库可能用的稍多一些,文件用起来较为方便,程序可以自己定义格式:数据库用起稍烦锁一些,但它有它的优点,比如在海量数 ...

  7. java解析xml的几种方式

    java解析xml的几种方式 DOM DOM的全称是Document ObjectModel,也即文档对象模型.在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称D ...

  8. uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式

    前言: 关于H5的调用Android原生方法的方式有很多,在该片文章中我主要简单介绍三种与Android原生方法交互的方式. 一.H5+方法调用android原生方法 H5+ Android开发规范官 ...

  9. Hadoop之HDFS文件操作常有两种方式(转载)

    摘要:Hadoop之HDFS文件操作常有两种方式,命令行方式和JavaAPI方式.本文介绍如何利用这两种方式对HDFS文件进行操作. 关键词:HDFS文件    命令行     Java API HD ...

随机推荐

  1. ASP+ACCESS手工注入详解

    SQL注入这么长时间,看见有的朋友还是不会手工注入,那么我来演示一下.高手略过. 我们大家知道,一般注入产生在没经过虑的变量上,像ID?=XX这样的. 下面以这个网址为例: http://zsb.xx ...

  2. JS 键值对

    function Map() { this.keys = new Array(); this.data = new Array(); //添加键值对 this.set = function (key, ...

  3. 闲来无事,用Java的软引用写了一个山寨的缓存

    闲来无事,用Java的软引用写了一个山寨的缓存 博客分类: java基础 众所周知java中的引用分为 StrongReference.SoftReference.WeakReference.Phan ...

  4. sturct stat 结构体中 st_mode 的含义

    工作中遇到 else if( (s_buf.st_mode&S_IFMT) == S_IFDIR) return 2; else if( !(s_buf.st_mode&S_IFREG ...

  5. linux下面覆盖文件,如何实现直接覆盖,不提示

    转自:http://w-tingsheng.blog.163.com/blog/static/2505603420124309130528/ cp覆盖时,无论加什么参数-f之类的还是提示是否覆盖,当文 ...

  6. Swift学习笔记

    swift 面向过程 数据结构 3.1 常量和变量 定义常量和变量 let a = 1 var b = 2 显式定义和隐式定义 无需指定强类型,编译器会自动根据初始值推断出其类型.与c#相似.如果在定 ...

  7. 关于angularjs 中自定义过滤器

    包子认为,在angularjs中,经常需要用到自定义过滤器,来过滤相应的功能,自定义过滤器非常的简单,我就直接贴代码啦 其中input就是你需要进行操作的对象,,,用法就直接就是 是不是很easy.. ...

  8. zstu.4191: 无向图找环(dfs树 + 邻接表)

    4191: 无向图找环 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 117  Solved: 34 Description 给你一副无向图,每条边有 ...

  9. 破解LR时,解决loadrunner 破解错误:license security violation.Operation is not allowed

    一.由于在压力测试执行中,出现一个-10803的错误 ,为解决这个错误,重新设置的环境变量,在次执行错误,这个问题解决了,但另外一个问题出来了,LR,打开脚本编辑器老提示找不到TEMP目录,当时没有想 ...

  10. JS获取汉字首字母

    //获取 汉字首字母 function makePy(str) { if (typeof (str) != "string") throw new Error(-1, " ...