• android 中的 xml 解析方法


    常用的方法有三种 分别是 sax ,dom , pull;

    在org 中 org.w3c.dom  、org.w3c.dom.ls、org.xml.sax、org.xml.sax.ext、org.xml.sax.helpers、org.xmlpull.v1、org.xmlpull.v1.sax2 定义了  dom 、sax、pull的接口

    在javax中 javax.xml.parsers 中定义了 dom 和 sax 的 解析接口 和工厂 (DocumentBuilder 、 SAXParser 和 DocumentBuilderFactory、SAXParserFactory)

    在 android.util 中 定义了 pull 的 工厂(Xml),org中也提供了 pull的工厂 和解析类

    1、sax 方法:

    /**
     *
     * SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。
     * SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,
     * SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。
     *     所谓事件,其实就是一些回调方法,这些方法(事件)定义在ContentHandler接口。
    *一般需要继承 DefaultHandler 重写里面的回调方法
     */
    public
    List<Person> saxParser(InputStream is) { try { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); // 创建解析器 SaxHandler handler = new SaxHandler(); saxParser.parse(is, handler); is.close(); return handler.getPersons(); } catch (Exception e) { e.printStackTrace(); } return null; }


    2、dom方法:
    /**
         *
         * 除了可以使用 SAX解析XML文件,大家也可以使用熟悉的DOM来解析XML文件。
         * DOM解析XML文件时,会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。
         * 使用DOM操作XML的代码看起来比较直观,并且,在某些方面比基于SAX的实现更加简单。
         * 但是,因为DOM需要将XML文件的所有内容读取到内存中,所以内存的消耗比较大,
         * 特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX来解析XML文件,
         * 当然,如果XML文件的内容比较小采用DOM是可行的。
         *
         * dom方式需要先生成 dom树,然后从中提取需要的内容 sax 直接从字节流中获取需要的内容,并且建立自定义的数据结构
         *
         * @param is
         * @return
         */
        public List<Person> domParser(InputStream is)
        {
            List<Person> persons = new ArrayList<Person>();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            try
            {
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document dom = builder.parse(is);
                Element root = dom.getDocumentElement();
                NodeList items = root.getElementsByTagName("person");// 查找所有person节点
                for (int i = 0; i < items.getLength(); i++)
                {
                    Person person = new Person();
                    // 得到第一个person节点
                    Element personNode = (Element) items.item(i);
                    // 获取person节点的id属性值
                    person.setId(new Integer(personNode.getAttribute("id")));
                    // 获取person节点下的所有子节点(标签之间的空白节点和name/age元素)
                    NodeList childsNodes = personNode.getChildNodes();
                    for (int j = 0; j < childsNodes.getLength(); j++)
                    {
                        Node node = (Node) childsNodes.item(j); // 判断是否为元素类型
                        if (node.getNodeType() == Node.ELEMENT_NODE)
                        {
                            Element childNode = (Element) node;
                            // 判断是否name元素
                            if ("name".equals(childNode.getNodeName()))
                            {
                                // 获取name元素下Text节点,然后从Text节点获取数据
                                person.setName(childNode.getFirstChild().getNodeValue());
                            }
                            else if ("age".equals(childNode.getNodeName()))
                            {
                                person.setAge(new Short(childNode.getFirstChild().getNodeValue()));
                            }
                        }
                    }
                    persons.add(person);
                }
                is.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return persons;
        }

    3、pull方法

    /**
         * 除了可以使用 SAX和DOM解析XML文件,大家也可以使用Android内置的Pull解析器解析XML文件。
         * Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,
         * 如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。
         * 事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,
         * 调用parser.nextText()方法可以获取下一个Text类型元素的值。
         *
         * 但 Xml pull 比 Sax 更简明,而且不需要扫描完整个流。它通过使用 nextext 控制扫描进度
         *
         * @param is
         * @return
         */
        public List<Person> pullParser(InputStream is)
        {
            XmlPullParser parser = Xml.newPullParser();
            try
            {
                parser.setInput(is, "UTF-8");
                int eventType = parser.getEventType();
                Person currentPerson = null;
                List<Person> persons = null;
                while (eventType != XmlPullParser.END_DOCUMENT)
                {
                    switch (eventType)
                    {
                    case XmlPullParser.START_DOCUMENT:// 文档开始事件,可以进行数据初始化处理
                        persons = new ArrayList<Person>();
                        break;
                    case XmlPullParser.START_TAG:// 开始元素事件
                        String name = parser.getName();
                        if (name.equalsIgnoreCase("person"))
                        {
                            currentPerson = new Person();
                            currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));
                        }
                        else if (currentPerson != null)
                        {
                            if (name.equalsIgnoreCase("name"))
                            {
                                currentPerson.setName(parser.nextText());// 如果后面是Text元素,即返回它的值
                            }
                            else if (name.equalsIgnoreCase("age"))
                            {
                                currentPerson.setAge(new Short(parser.nextText()));
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:// 结束元素事件

                        if (parser.getName().equalsIgnoreCase("person") && currentPerson != null)
                        {
                            persons.add(currentPerson);
                            currentPerson = null;
                        }
                        break;
                    }
                    eventType = parser.next();
                }
                is.close();
                return persons;
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }

    1、dom 需要读入保存整个文件,生成一颗document 数,然后可以从中选择需要的节点、属性;
    2、sax 需要扫描整个文件,并且封装事件驱动
    3、pull 不需要扫码整个文件,可以使用nextText控制扫码进度,也是事件驱动,但没有封装。
  • 相关阅读:
    如何正确记忆单词
    转:超级通用型分页存储过程
    Delphi报表开发ReportMachine的小计和总计的计算
    DELPHI编程用SQLDMO呈现带进度条的SQL Server数据库Databnse备份!
    datasnap 2010 心跳包,连接断开处理
    合并BPL包图文教程
    Borland DataSnap(MIDAS)三层架构编程中,主细表的处理方式
    网上摘的 杀进程函数
    为RB定制支持参数的自定义函数
    获取一个数据库中的所有表的名称、一个表中所有字段的名称
  • 原文地址:https://www.cnblogs.com/lipeil/p/2625055.html
Copyright © 2020-2023  润新知