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"?>
<persons>
    <person id="1" key="33" type="type">
        <name>zhangsan</name>
        <age>21</age>
    </person>
</persons>

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就是">"到下一个"<"的长度。
         *  <namesList>
         *      <name>michael</name>
         *  </namesList>
         *  执行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就是签的称,如本文所示范的,当解析到第一个人名的时光,

<person id="1" key="33" type="type">
    <name>zhangsan</name>
    <age>21</age>
</person>

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

  • characters,解析到标签的内容时回调,接着上面例子,解析<person></person>,回调startElement,然后不会见回调此方法,因为内容无是文件,而是包含了签,所以,解析到其子标签:<name>zhangsan</name>的当儿,又会预先回调回调startElement,然后,才回调characters,告诉你,这个标签中有文件内容!参数说明如下:

  • char[] :
    内容字符数组里面。如:<name>zhangsan</name>,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
  • 分析到第一只标签的起来:<persons>
  • 接下来解析及了内容???characters?按照自上面的辨析,<persons>标签内并未字内容,应该不见面回调。其实,这里回调的凡换行符。log中由来了ASCII码,10便是换行。然后,还有一个tab符。
  • 接下来就<persons>里面的<person>,有三单参数: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' ?>
<persons>
    <person id="1" key="33" type="type">
        <name>zhangsan</name>
        <age>21</age>
    </person>
    <person>
        <name>lisi</name>
        <age>12</age>
    </person>
    <person>
        <name>wangwu</name>
        <age>23</age>
    </person>
</persons>
  • 首先你得定义好一个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<Person> 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,再保存即可。

相关文章

网站地图xml地图