【Android】使用Pull生成/解析XML文件

、生成XML文件,即是将对象集合转为XML文件存储。
对象集合 –> XML(序列化)

Android中使用android.util.Xml类对其进行了描述,提供相应的API。
步骤大致如下:

  1. 创建一个XmlSerializer类的实例,XmlSerializer serializer = Xml.newSerializer()。
  2. 使用openFileOutput准备一个输出流,指定输出的xml文件名及该文件权限。
  3. 给序列化serializer对象设置输出流和编码格式。
  4. serializer设置xml的编码格式,文档的开始。
  5. serializer设置xml的根节点,根节点的标签。
  6. 使用for循环遍历集合中的所有对象,为每一个对象写入标签和属性。
  7. 根节点的结束。
  8. 文档的结束。

测试代码如下:

准备一个数据模型PersonInfo类

public class PersonInfo {

    public int id;
    public String name;
    public int age;

    public PersonInfo() {
        super();
    }

    public PersonInfo(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "PersonInfo{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

然后在MainActivity中准备一个按钮,生成XML。

/**
 * 按钮点击事件,对象集合->XML
 * @param view
 */
public void createXml(View view){
    try {
    // 准备一个集合
    List<PersonInfo> infos = new ArrayList<PersonInfo>();
    // 添加两个对象数据
    infos.add(new PersonInfo(1, "老王", 20));
    infos.add(new PersonInfo(2, "老张", 30));
    // 把对象集合变为XML
    XmlSerializer serializer = Xml.newSerializer();
    FileOutputStream os = openFileOutput("persons.xml", Context.MODE_PRIVATE); // 指定输出的文件名及其访问权限
    serializer.setOutput(os, "utf-8");       // 指定输出流及编码格式
    serializer.startDocument("utf-8", true); // 文档的开始
    serializer.startTag(null, "persons");    // 根节点的开始
    // 给每个对象写入标签和属性
    for(PersonInfo info:infos){
        // 属性
        serializer.startTag(null, "person");
        serializer.attribute(null, "id", info.id + "");
        // name
        serializer.startTag(null, "name");
        serializer.text(info.name); // 文本节点
        serializer.endTag(null, "name");
        // age
        serializer.startTag(null, "age");
        serializer.text(info.age + "");
        serializer.endTag(null, "age");

        serializer.endTag(null, "person");
    }

    serializer.endTag(null, "persons"); // 根节点的结束
    serializer.endDocument();           // 文档的结束

    os.close(); // 关流

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

运行程序,点击生成XML按钮后,在data/data/包名/files路径下生成了persons.xml文件。
这里写图片描述

导出该文件,看内容如下(无换行、无缩进):

<?xml version='1.0' encoding='utf-8' standalone='yes' ?><persons><person id="1"><name>老王</name><age>20</age></person><person id="2"><name>老张</name><age>30</age></person></persons>

手动调整了一下,可见效果如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<persons>
    <person id="1">
        <name>老王</name>
        <age>20</age>
    </person>
    <person id="2">
        <name>老张</name>
        <age>30</age>
    </person>
</persons>

、解析XML文件,即是将XML文件转为对象集合。
XML –> 对象集合 (反序列化)

Android中解析XML有三种方法:SAX、DOM、PULL,这里使用Android内置的Pull解析。
需要使用XmlPullParser类,步骤大致如下:

  1. 获得一个XmlPullParser类的实例。
  2. 给parser解析器对象设置xml文件及其编码格式。
  3. 从parser解析器对象身上获取解析到的事件类型。
  4. 用switch语句处理不同事件类型。

其中,事件类型有以下几种:

eventTypemean
START_DOCUMENT 文档开始
START_TAG 标签开始
TEXT 内容
START_END 标签结束
END_DOCUMENT 文档结束

在MainActivity中添加一个按钮,解析使用之前生成的persons.xml,代码如下:

/**
     * 按钮点击事件,解析xml文件。XML --> 对象集合
     * @param view
     */
    public void parseXml(View view){
        List<PersonInfo> infos = null;
        PersonInfo info = null;
        try {
            // 获取解析器
            XmlPullParser parser = Xml.newPullParser();
            // 准备一个输入流,传入要解析的xml文件
            FileInputStream inputStream = openFileInput("persons.xml");
            parser.setInput(inputStream, "utf-8"); // 把流设置给解析器
            int eventType = parser.getEventType(); // 获取事件类型

            while(eventType != XmlPullParser.END_DOCUMENT){ // 判断是否解析到了文档的结尾
                switch (eventType) {
                    case XmlPullParser.START_TAG: // 标签的开始
                        if("persons".equals(parser.getName())){ // 获取当前标签的名称,根节点的开始
                            infos = new ArrayList<PersonInfo>();
                        }else if("person".equals(parser.getName())){ // 获取当前标签的名称,一个对象的开始
                            info = new PersonInfo();
                            int id = Integer.parseInt(parser.getAttributeValue(0)); // 获取属性
                            info.id = id;
                        }else if("name".equals(parser.getName())){
                            String name = parser.nextText(); // 获取下一个文本节点的值
                            info.name = name;
                        }else if("age".equals(parser.getName())){
                            int age = Integer.parseInt(parser.nextText());
                            info.age = age;
                        }
                        break;
                    case XmlPullParser.END_TAG: // 标签的结束
                        if("person".equals(parser.getName())){
                            infos.add(info);
                            info = null;
                        }
                        break;

                    default:
                        break;
                }
                // 还没到文档的结尾,继续往下解析
                eventType = parser.next();
            }
            //打印日志
            for(PersonInfo personInfo:infos){
                Log.i(TAG, personInfo.toString());
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

以上代码的模板代码可以在XmlPullParser类的文档上看到!
运行后,点击解析XML按钮,结果如下:
这里写图片描述


其他:看了下边这篇博文,记录一下一个值得注意的点。

http://blog.csdn.net/onlyonecoder/article/details/8489170

这里写图片描述

 

posted @ 2016-10-27 20:48  霍莉雪特  阅读(444)  评论(0编辑  收藏  举报