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
  • 相关阅读:
    回调函数案例(二)
    回调函数案例(一)
    liteos学习文档liteos.github.io
    HeapAlloc、GlobalAlloc和new等内存分配有什么区别么?
    C语言中字符数组和字符串指针分析
    socket 连接,使得地址马上可以重用
    shutdown 和closesocket
    IP地址转换成Long型数字的算法
    WSAStartup( )
    关于完成端口IOCP异步接收连接函数AcceptEx注意事项
  • 原文地址:https://www.cnblogs.com/toly-top/p/9781891.html
Copyright © 2011-2022 走看看