Android Xml的三种解析方式

xml文件:从网络获取,或存在本地(assets目录下);

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<Persons>
    <person id="1">
        <name>张三</name>
        <sex></sex>
        <age>25</age>
        <path>http://192.168.5.10:8080/FileServer/chengjisihan.jpg</path>
    </person>
    <person id="2">
        <name>李斯</name>
        <sex></sex>
        <age>78</age>
        <path>http://192.168.5.10:8080/FileServer/laozi.jpg</path>
    </person>
    <person id="3">
        <name>王五</name>
        <sex></sex>
        <age>22</age>
        <path>http://192.168.5.10:8080/FileServer/lilongji.jpg</path>
    </person>
</Persons>

三种实现方法:pull、dom、sax

/**
 * xml解析:pull,dom,sax
 */

public class XmlTestActivity extends BaseAct<ActXmlTestBinding> {
    private ActXmlTestBinding testBinding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        testBinding = setContent(R.layout.act_xml_test);
        testBinding.btnPull.setOnClickListener(v -> {
            try {
                List<Person> pullPerson = parseXmlByPull();
                testBinding.tvResult.setText(pullPerson.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        testBinding.btnDom.setOnClickListener(v -> {
            try {
                testBinding.tvResult1.setText(parseXmlByDom().toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        testBinding.btnSax.setOnClickListener(v -> {
            try {
                testBinding.tvResult2.setText(parseXmlBySax().toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是:
     * 在PULL解析过程中,需要获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。
     * PULL解析器小巧轻便,解析快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析XML时也是用PULL解析
     */
    private List<Person> parseXmlByPull() throws Exception {
        List<Person> list = null;
        Person person = null;
        //创建xmlPull解析器
        XmlPullParser parser = Xml.newPullParser();
        ///初始化xmlPull解析器
        parser.setInput(getAssets().open("person.xml"), "utf-8");
        //读取文件的类型
        int type = parser.getEventType();
        //无限判断文件类型进行读取
        while (type != XmlPullParser.END_DOCUMENT) {
            switch (type) {
                //开始解析文档
                case XmlPullParser.START_DOCUMENT:
                    list = new ArrayList<>();
                    break;
                //开始标签
                case XmlPullParser.START_TAG:
                    if ("person".equals(parser.getName())) {
                        person = new Person();
                    } else if ("name".equals(parser.getName())) {
                        //获取name值
                        String name = parser.nextText();
                        person.setName(name);
                    } else if ("sex".equals(parser.getName())) {
                        //获取sex值
                        String sex = parser.nextText();
                        person.setSex(sex);
                    } else if ("age".equals(parser.getName())) {
                        //获取age值
                        String age = parser.nextText();
                        person.setAge(Integer.parseInt(age));
                    }
                    break;
                //结束标签
                case XmlPullParser.END_TAG:
                    if ("person".equals(parser.getName())) {
                        list.add(person);
                    }
                    break;
            }
            //继续读取标签类型
            type = parser.next();
        }
        return list;
    }

    /**
     * DOM解析的原理是基于树形的结构和信息数据集合:
     * 将文件分为独立的元素、属性和注释等,然后以节点树的形式在内存中对XML文件进行表示
     * 利用DOM中的对象,可以对XML文档进行读取、搜索、修改、添加和删除等操作。
     * @return
     * @throws Exception
     */
    private List<Person> parseXmlByDom() throws Exception {
        //一系列的初始化
        List<Person> itList = new ArrayList<>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        //获得Document对象
        Document document = builder.parse(getAssets().open("person.xml"));
        //获得List(本xml中就是根结点)
        NodeList personList = document.getElementsByTagName("person");
        //遍历person标签
        for (int i = 0; i < personList.getLength(); i++) {
            //获得person标签
            Node node_person = personList.item(i);
            //获得person标签里面的标签
            NodeList childNodes = node_person.getChildNodes();
            //新建对象
            Person person = new Person();
            //遍历person标签里面的标签
            for (int j = 0; j < childNodes.getLength(); j++) {
                Node childNode = childNodes.item(j);
                //判断是name还是其他
                if ("name".equals(childNode.getNodeName())) {
                    String name = childNode.getTextContent();
                    person.setName(name);
                } else if ("sex".equals(childNode.getNodeName())) {
                    String sex = childNode.getTextContent();
                    person.setSex(sex);
                } else if ("age".equals(childNode.getNodeName())) {
                    String age = childNode.getTextContent();
                    person.setAge(Integer.parseInt(age));
                }
            }
            //加到List中
            itList.add(person);
        }
        return itList;
    }

    /**
     * 描述:
     * SAX解析核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的,也就是ContentHandler为重要核心。
     * 解析过程中每遇到一个事件源,只有调用事件解析器才能得到相应的处理;不过它的优点主要是解析速度快,占用内存少。
     * 非常适合在Android移动设备中使用
     * 参数说明:
     */
    private List<Person> parseXmlBySax() throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        //初始化Sax解析器
        SAXParser sp = spf.newSAXParser();
        //新建解析处理器
        SaxparseHandler handler = new SaxparseHandler();
        //将解析交给处理器
        sp.parse(getAssets().open("person.xml"), handler);
        //返回List
        return handler.getList();
    }

    public class SaxparseHandler extends DefaultHandler {

        private List<Person> list;
        private Person person;
        //用于存储读取的临时变量
        private String tempString;

        /**
         * 解析到文档开始
         */
        @Override
        public void startDocument() throws SAXException {
            list = new ArrayList<>();
            super.startDocument();
        }

        /**
         * 解析到文档末尾调用
         */
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }

        /**
         * 每读到一个元素就调用
         */
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if ("person".equals(qName)) {
                //读到person标签
                person = new Person();
            }
            super.startElement(uri, localName, qName, attributes);
        }

        /**
         * 读到元素的结尾时调用
         */
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ("person".equals(qName)) {
                list.add(person);
            }
            if ("name".equals(qName)) {
                person.setName(tempString);
            } else if ("sex".equals(qName)) {
                person.setSex(tempString);
            } else if ("age".equals(qName)) {
                person.setAge(Integer.parseInt(tempString));
            }
            super.endElement(uri, localName, qName);
        }

        /**
         * 读到属性内容调用
         */
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            tempString = new String(ch, start, length);
            super.characters(ch, start, length);
        }

        /**
         * 获取该List并返回
         */
        public List<Person> getList() {
            return list;
        }
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_pull"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="pull" />

        <Button
            android:id="@+id/btn_dom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="dom" />

        <Button
            android:id="@+id/btn_sax"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="sax" />
        <TextView
            android:id="@+id/tv_result"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/tv_result1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/tv_result2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>
</layout>

运行结果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值