• 3-SIII-Android数据固化之Xml的Sax解析和存储


    零、前言

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

    Sax解析概述:(Simple API for XML)
    Sax解析方式会逐行地去扫描XML文档,当遇到标签时会触发解析处理器,采用事件处理的方式解析XML 
    优点:在读取文档的同时即可对XML进行处理,不必等到文档加载结束,相对快捷,所以可以解析超大XML
    缺点:只能用来读取XML中数据,无法进行增删改。
    
    准备的待解析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>
    

    一、Sax解析Xml

    /**
     * 
     * @return
     */
    private ArrayList<WeaponXml> parseXmlWithSax() {
        InputStream is = null;
        mWeapons = new ArrayList<>();
        try {
            SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
            is = getAssets().open("weapon.xml");
            saxParser.parse(is, new DefaultHandler() {
                /**
                 *  开始标签时
                 * @param uri 命名空间
                 * @param localName 标签名
                 * @param qName 全名(带命名空间的标签的名字)
                 * @param attributes 属性
                 * @throws SAXException
                 */
                @Override
                public void startElement(String uri, String localName,
                                         String qName, Attributes attributes) throws SAXException {
                    //"属性名:" + attributes.getLocalName(i)
                    //"属性值:" + attributes.getValue(i));
                    if ("weapon".equals(localName)) {
                        mWeapon = new WeaponXml();
                        mWeapon.setMaterial(attributes.getValue(0));
                        mWeapon.setType(attributes.getValue(1));
                    }
                    mPerTag = localName;
                }
                /**解析标签的内容的时候调用
                 *
                 * @param ch 当前文本节点的字节数组
                 * @param start 字节开始的位置 默认 0 全部读取
                 * @param length 长度
                 * @throws SAXException
                 */
                @Override
                public void characters(char[] ch, int start, int length) throws SAXException {
                    String chars = new String(ch, start, length).trim();
                    if ("name".equals(mPerTag)) {
                        mWeapon.setName(chars);
                    } else if ("atk".equals(mPerTag)) {
                        mWeapon.setAtk(Integer.parseInt(chars));
                    } else if ("user".equals(mPerTag)) {
                        mWeapon.setUser(chars);
                    }
                }
                /**
                 * 标签解析结束调用
                 * @param uri
                 * @param localName
                 * @param qName
                 * @throws SAXException
                 */
                @Override
                public void endElement(String uri, String localName, String qName) throws SAXException {
                    if ("weapon".equals(localName)) {
                        mWeapons.add(mWeapon);
                        mWeapon = null;
                    }
                    mPerTag = null;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return mWeapons;
    }
    

    二、Sax存储Xml

    /**
     * sax创建Xml文件
     */
    private void saxCreateXml() {
        ArrayList<WeaponXml> weaponXmls = parseXmlWithSax();
        //1、创建一个SAXTransformerFactory的对象
        SAXTransformerFactory saxTF = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        FileOutputStream fos = null;
        try {
            //创建一个Transformer对象
            TransformerHandler handler = saxTF.newTransformerHandler();
            Transformer transformer = handler.getTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            fos = new FileOutputStream(path + File.separator + "weaponSax.xml");
            StreamResult result = new StreamResult(fos);
            handler.setResult(result);
            //开始
            handler.startDocument();
            AttributesImpl atts = new AttributesImpl();
            handler.startElement("", "", "weapons", atts);
            for (WeaponXml weaponXml : weaponXmls) {
                atts.clear();
                atts.addAttribute("", "", "material", "", weaponXml.getMaterial());
                atts.addAttribute("", "", "type", "", weaponXml.getType());
                handler.startElement("", "", "weapon", atts);
                atts.clear();
                handler.startElement("", "", "name", atts);
                handler.characters(weaponXml.getName().toCharArray(), 0, weaponXml.getName().length());
                handler.endElement("", "", "name");
                atts.clear();
                handler.startElement("", "", "atk", atts);
                String atk = String.valueOf(weaponXml.getAtk());
                handler.characters(atk.toCharArray(), 0, atk.length());
                handler.endElement("", "", "atk");
                atts.clear();
                handler.startElement("", "", "user", atts);
                handler.characters(weaponXml.getUser().toCharArray(), 0, weaponXml.getUser().length());
                handler.endElement("", "", "user");
                handler.endElement("", "", "weapon");
            }
            handler.endElement("", "", "weapons");
            //关闭document
            handler.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
  • 相关阅读:
    Windows API 第六篇 GetLocalTime
    _itoa _itow _itot atoi atof atol
    Window API 第五篇 WTSEnumerateProcesses
    获取计算机以及本机信息API
    Windows API 第四篇 文件操作
    [软工顶级理解组] 团队介绍和采访!
    2019 SDN上机第1次作业
    第01组 团队项目-需求分析报告
    团队项目-选题报告
    第二次结对编程作业
  • 原文地址:https://www.cnblogs.com/toly-top/p/9781890.html
Copyright © 2020-2023  润新知