zoukankan      html  css  js  c++  java
  • 2-SIII-Android数据固化之Xml的Pull解析和存储

    零、前言

    Xml是一种应用广泛的标记语言,我们常见的html便是它的子集。形如:<XXX>xxx</XXX>组成的闭合标签
    安卓的res目录下的xml想必大家都是否熟悉,它们最终都是在代码中被读取并解析发挥效果的
    安卓的SharedPreferences是以Xml的形式存储数据的,就连AndroidManifest注意一看也是Xml
    可以说xml涉及到了安卓的很多方面,我们并不陌生,Xml最大的好处就是解耦,容易复用和更换
    安卓的Xml解析有Pull解析、Sax解析和Dom解析,这篇先说Pull解析
    先读一个xml,再将这个xml写入SD卡(运行时权限自己注意)

    9414344-4e57a5fd1184059f.png
    pull解析.png
    Pull解析概述
    Pull是安卓内置的,基于事件触发的解析器
    Pull解析器小巧轻便,解析速度快,简单易用
    主动从解析器中获取事件,可以在满足了需要的条件后不再获取事件,结束解析
    
    准备的待解析xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <weapons>
        <weapon material="玉" type="剑">
            <name>问天剑</name>
            <atk>2000</atk>
            <user>语熙华</user>
        </weapon>
        <weapon material="铁" type="刀">
            <name>皇刀</name>
            <atk>3000</atk>
            <user>九方玄玉</user>
        </weapon>
    </weapons>
    

    一、解析Xml:

    private ArrayList<WeaponXml> parseXmlWithPull() {
        InputStream is = null;
        try {
            //XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            //XmlPullParser pullParser = factory.newPullParser();
            //获得Xml解析器--等价上两句
            XmlPullParser pullParser = Xml.newPullParser();
            //得到一个含有xml的is输入流
             is = getAssets().open("weapon.xml");
            //设置输入流
            pullParser.setInput(is, "utf-8");
            //触发第一个事件:eventType=0 即:START_DOCUMENT
            int eventType = pullParser.getEventType();
            //没有读到文档结束之前都在while里走
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {//根据事件类型执行
                    case XmlPullParser.START_DOCUMENT://文档开始
                        //新建对象的集合
                        mWeapons = new ArrayList<>();
                        break;
                    case XmlPullParser.START_TAG://读到第一个标签时再进行switch选择
                        switch (pullParser.getName()) {//拿到标签名称
                            case "weapon"://如果标签是weapon
                                //新建一个 Weapon对象用来记录信息
                                mWeapon = new WeaponXml();
                                //获取第一个属性值
                                String material = pullParser.getAttributeValue(0);
                                //获取第二个属性值
                                String type = pullParser.getAttributeValue(1);
                                //对象装载得到的属性
                                mWeapon.setType(type);
                                mWeapon.setMaterial(material);
                                break;
                            case "name":
                                //对于没有属性的标签,可以用nextText获取标签内部的文字
                                String name = pullParser.nextText();
                                mWeapon.setName(name);
                                break;
                            case "atk":
                                Short atk = new Short(pullParser.nextText());
                                mWeapon.setAtk(atk);
                                break;
                            case "user":
                                String user = pullParser.nextText();
                                mWeapon.setUser(user);
                                break;
                        }
                        break;
                    case XmlPullParser.END_TAG://当事件类型是终止标签时:即</XXX>
                        if ("weapon".equals(pullParser.getName())) {
                            mWeapons.add(mWeapon);//将生成对象加入集合,一个
                        }
                        break;
                }
                eventType = pullParser.next();//解析下一元素,更新event
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (is != null) {
                try {
                    is.close();//关流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return mWeapons;
    }
    

    二、Xml的写入:

        /**
         * 备份Xml--当然也可以备份任意的实体类作为Xml,比如短信,联系人
         */
        private void backUpXml() {
            ArrayList<WeaponXml> weapons = parseXmlWithPull();
            XmlSerializer serializer = Xml.newSerializer();
            FileOutputStream fos = null;
            try {
                String path = Environment.getExternalStorageDirectory().getAbsolutePath();
                 fos = new FileOutputStream(path + File.separator + "weapon.xml");
    
                serializer.setOutput(fos, "utf-8");
                //文档开始
                serializer.startDocument("utf-8", true);
                serializer.startTag("", "weapons");
                for (WeaponXml weapon : weapons) {
                    //新建标签: <weapon>
                    serializer.startTag(null, "weapon");
                    //设置属性: material="玉" type="剑"
    
                    serializer.attribute("","material", weapon.getMaterial());
                    serializer.attribute("","type", weapon.getType());
                    //嵌套子标签:<name>问天剑</name>
                    serializer.startTag(null, "name");
                    serializer.text(weapon.getName().trim());
                    serializer.endTag(null, "name");
    
                    serializer.startTag(null, "atk");
                    serializer.text(weapon.getAtk() + "");
                    serializer.endTag(null, "atk");
    
                    serializer.startTag(null, "user");
                    serializer.text(weapon.getUser().trim());
                    serializer.endTag(null, "user");
                    //终止标签: </weapon>
                    serializer.endTag(null, "weapon");
                }
                serializer.endTag("", "weapons");//标签结束
                serializer.endDocument();//文档结束
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
    

    后记、

    1.声明:

    [1]本文由张风捷特烈原创,转载请注明
    [2]欢迎广大编程爱好者共同交流
    [3]个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
    [4]你的喜欢与支持将是我最大的动力

    2.连接传送门:

    更多安卓技术欢迎访问:安卓技术栈
    我的github地址:欢迎star
    简书首发,腾讯云+社区同步更新
    张风捷特烈个人网站,编程笔记请访问:http://www.toly1994.com

    3.联系我

    QQ:1981462002
    邮箱:1981462002@qq.com
    微信:zdl1994328

    4.欢迎关注我的微信公众号,最新精彩文章,及时送达:
    9414344-c474349cd3bd4b82.jpg
    公众号.jpg
  • 相关阅读:
    PHP 5.5.0 Alpha5 发布
    Ubuntu Touch 只是另一个 Android 皮肤?
    MariaDB 10 已经为动态列提供文档说明
    Percona Toolkit 2.1.9 发布,MySQL 管理工具
    Oracle Linux 6.4 发布
    Ruby 2.0.0 首个稳定版本(p0)发布
    Apache Pig 0.11.0 发布,大规模数据分析
    Node.js 0.8.21 稳定版发布
    红薯 MySQL 5.5 和 5.6 默认参数值的差异
    Django 1.5 正式版发布,支持 Python 3
  • 原文地址:https://www.cnblogs.com/toly-top/p/9781891.html
Copyright © 2011-2022 走看看