0. Thanks

Android解析XML的三种方式
Android几种解析XML方式的比较
android xml 解析 修改
android 对xml文件的pull解析,生成xml ,对xml文件的增删

1.概述

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

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

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

<?xml version="1.0" encoding="UTF-8"?>            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 < attributes.getLength(); i++) {                    Log.i("loadWithSax",attributes.getLocalName(i)+","+attributes.getValue(i)+","+attributes.                }            }        }        //标签解析结束        @Override        public void endElement(String uri, String localName, String qName) throws SAXException {            super.endElement(uri, localName, qName);            Log.i("loadWithSax","endElement"+",uri:"+uri+",localName:"+localName+",qName:"+qName);        }        /**         *  文本         *  该方法中的ch把所解析的xml的所有数据都保存进来,且ch初始化为2K数据。 start是一个节点">"的位置。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 < ch.length; i++) {                Log.i("loadWithSax","char:"+ch[i]+",ASCII:"+(int)ch[i]);            }        }        //警告回调        @Override        public void warning(SAXParseException e) throws SAXException {            super.warning(e);            Log.i("loadWithSax","warning"+","+e.getMessage());        }        //错误回调        @Override        public void error(SAXParseException e) throws SAXException {            super.error(e);            Log.i("loadWithSax","error1"+","+e.getMessage());        }    });} catch (ParserConfigurationException | SAXException | IOException e) {    e.printStackTrace();    Log.i("loadWithSax","error2"+","+e.getMessage());}
  • 传入: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: startDocumentI/loadWithSax: startElement,uri:,localName:persons,qName:personsI/loadWithSax: characters,start:0,length:1I/loadWithSax: char:               ,ASCII:10I/loadWithSax: characters,start:0,length:1I/loadWithSax: char:    ,ASCII:9I/loadWithSax: startElement,uri:,localName:person,qName:personI/loadWithSax: id,1,CDATAI/loadWithSax: key,33,CDATAI/loadWithSax: type,type,CDATAI/loadWithSax: characters,start:0,length:1I/loadWithSax: char:               ,ASCII:10I/loadWithSax: characters,start:0,length:2I/loadWithSax: char:    ,ASCII:9I/loadWithSax: char:    ,ASCII:9I/loadWithSax: startElement,uri:,localName:name,qName:nameI/loadWithSax: characters,start:0,length:8I/loadWithSax: char:z,ASCII:122I/loadWithSax: char:h,ASCII:104I/loadWithSax: char:a,ASCII:97I/loadWithSax: char:n,ASCII:110I/loadWithSax: char:g,ASCII:103I/loadWithSax: char:s,ASCII:115I/loadWithSax: char:a,ASCII:97I/loadWithSax: char:n,ASCII:110I/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:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>            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);//...同上//记得closeif (stringWriter != null) {    stringWriter.close();}

4.增删

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

更多相关文章

  1. 安全新手入坑——HTML标签
  2. Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效
  3. APP测试的内容(一)
  4. Android(安卓)Scroll详解(一):基础知识
  5. Android(安卓)WebView用法和WebView加载提升网页速度
  6. Android(安卓)中SoftAP架构研究
  7. Android中动态修改string.xml中字符串的内容
  8. android周记1
  9. Android之Tab分页标签的实现方法一-----TabActivity和TabHost的

随机推荐

  1. android滑动翻页主界面
  2. Android经验: proguard 阻碍 webview 正
  3. Android TextView带背景图片和自定义边框
  4. Mac 配置android NDK
  5. 几种常见的xml解析方式 SAX,DOM,PULL以an
  6. Android透明状态栏的实现方法
  7. Android 简单的图片查看器源码实现
  8. Android(安卓)小項目之---标准体重测量仪
  9. android 阻塞 对话框 完全阻塞 停止主进
  10. Android 自动接听电话