文档章节

[Android] android平台下sax,dom,pull解析方式性能比较

枫兮兮
 枫兮兮
发布于 2014/02/27 00:35
字数 1158
阅读 86
收藏 1

1.Android中三种XML的解析方式,分别为Dom,Sax,Pull,其中Pull的解析方式最优

2.Dom,Sax,Pull解析方式的区别

(1).Dom解析方式:

首先一下子加载整个文档然后再挨个节点解析,费流量

优点:对于处理大文档,以及能力强的CPU性能比较快

缺点:对于处理能力不够强的CPU一下子可能受不了,就像一个人一口先吃下一个大西瓜,再来嚼.

(2).Sax解析方式:

SAX是事件驱动型解析方式

虽说是事件驱动型的和PULL差不多,但没有像pull那样提供next接口,想向下继续解析就向下,没有灵活性,死板,包括得到数据也是用模板弄好,对于特殊的数据组装还要用变量控制。

sax是选择性的解析,他是解析符合条件的内容。

手动停止:
解析完需要的东西后就抛异常吧,比如throw new SAXException("已拿到数据,中断解析!!!");

(3).Pull的解析方式:

Pull驱动型解析方式,加载时不把所有的节点都加载到解析机里,只是去一个一个节点去查找,如果是一个节点而且需要这个节点就取出来,不像DOM,不管你要不要都放在解析机里,要拿就拿,不拿就算了.,减少流量的使用

3.综上觉得Pull解析方式最优,通过调试代码发现,解析同一个XML文件,pull解析方式花的时间最少.

核心代码如下:

//DOM解析方式

private List<River> fetchRiverFromXmlByDom(String fileName) {

    long startTime = System.currentTimeMillis();

    List<River> rivers = new ArrayList<River>();

    // 加载xml文档的工厂

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

    InputStream inputStream = null;

    try {

        DocumentBuilder builder = factory.newDocumentBuilder();

        // 加入文件流

        inputStream = getAssets().open(fileName);

        // 转化为decument文档对象

        Document document = builder.parse(inputStream);

        // 获得最根节点

        Element root = document.getDocumentElement();

        // 通过tag获得所有根节点下面的节点

        NodeList nodeList = root.getElementsByTagName(riverStr);

        // 得到根节点下面有多少个节点

        int noteListSize = nodeList.getLength();

        // 声明river对象,river类中包含所有的节点string

        River river = null;

        for (int i = 0; i < noteListSize; i++) {

            river = new River();

            // 获得节点元素

            Element element = (Element) nodeList.item(i);

            // 设置通过属性名得到的节点元素

            river.setName(element.getAttribute(nameStr));

            river.setLength(Integer.parseInt(element.getAttribute(lengthStr)));

            // 通过tag名得到所有节点,再取得第一个节点(因为只有一个节点,如果这里面还有节点得再来一个类似的循环)

            Element introTag = (Element) element.getElementsByTagName(introductionStr).item(0);

            river.setIntroduction(introTag.getFirstChild().getNodeValue());

            Element imageUrlTag = (Element) element.getElementsByTagName(imageurlStr).item(0);

            river.setImageurl(imageUrlTag.getFirstChild().getNodeValue());

            // 收集所有的节点到这个集合里

            rivers.add(river);

        }

    } catch (ParserConfigurationException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    } catch (SAXException e) {

        e.printStackTrace();

    }

    Log.d(T, "exec fetchRiverFromXmlByDom use time = "

            + (System.currentTimeMillis() - startTime));

    return rivers;

}

SAX解析方式:

private List<River> fetchRiverFormXmlBySAX(String fileName) {

    long startTime = System.currentTimeMillis();

    List<River> rivers = null;

    SAXParserFactory factory = SAXParserFactory.newInstance();

    InputStream inputStream = null;

    try {

        //得到解析机

        SAXParser parser = factory.newSAXParser();

        //读取数据

        XMLReader reader = parser.getXMLReader();

        //取数据的句柄

        MySaxHandler handler = new MySaxHandler();

        reader.setContentHandler(handler);

        inputStream = getAssets().open(fileName);

        reader.parse(new InputSource(inputStream));

        rivers = handler.getRivers();

    } catch (ParserConfigurationException e) {

        e.printStackTrace();

    } catch (SAXException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    }

    Log.d(T, "exec fetchRiverFormXmlBySAX use time = "

            + (System.currentTimeMillis() - startTime));

    return rivers;

}



private class MySaxHandler extends DefaultHandler {



    private List<River> rivers = null;



    private boolean isRiver = false;



    private boolean isIntrocduce = false;



    private boolean isImageUrl = false;



    private River river = null;



    private String TAG = "MySaxHandler";



    public MySaxHandler() {

        rivers = new ArrayList<River>();

    }



    @Override

    public void startDocument() throws SAXException {

        super.startDocument();

        Log.d(TAG, "### startDocument");

    }



    @Override

    public void endDocument() throws SAXException {

        super.endDocument();

        Log.d(TAG, "### endDocument");

    }



    @Override

    public void startElement(String uri, String localName, String qName,

            Attributes attributes) throws SAXException {

        super.startElement(uri, localName, qName, attributes);

        String tagName = localName.length() > 0 ? localName : qName;

        if (tagName.equals(riverStr)) {

            isRiver = true;

            river = new River();

            river.setName(attributes.getValue(nameStr));

            river.setLength(Integer.parseInt(attributes.getValue(lengthStr)));

        }

        if (isRiver) {

            if (tagName.equals(introductionStr)) {

                isIntrocduce = true;

            } else if (tagName.equals(imageurlStr)) {

                isImageUrl = true;

            }

        }



    }



    @Override

    public void endElement(String uri, String localName, String qName)

            throws SAXException {

        super.endElement(uri, localName, qName);

        // Log.d(TAG, "### endElement uri=" + uri + " localName=" +

        // localName + " qName=" + qName);

        String tagName = localName.length() != 0 ? localName : qName;

        if (tagName.equals(riverStr)) {

            isRiver = false;

            rivers.add(river);

        }

        if (isRiver) {

            if (tagName.equals(introductionStr)) {

                isIntrocduce = false;

            } else if (tagName.equals(imageurlStr)) {

                isImageUrl = false;

            }

        }

    }



    @Override

    public void characters(char[] ch, int start, int length)

            throws SAXException {

        super.characters(ch, start, length);

        if (isIntrocduce) {

            river.setIntroduction(river.getIntroduction() == null ? "" : river

                    .getIntroduction() + new String(ch, start, length));

        } else if (isImageUrl) {

            river.setImageurl(river.getImageurl() == null ? "" : river.getImageurl()

                    + new String(ch, start, length));

        }

    }



    public List<River> getRivers() {

        return rivers;

    }



}

Pull解析方式:

private List<River> fetchRiverFormXmlByPull(String fileName) {

    long startTime = System.currentTimeMillis();

    List<River> rivers = new ArrayList<River>();

    River river = null;

    InputStream inputStream = null;

    // 获得解析机对象

    XmlPullParser xmlPullParser = Xml.newPullParser();

    try {

        // 得到文件流

        inputStream = getAssets().open(fileName);

        xmlPullParser.setInput(inputStream, "utf-8");

        // 获得命名空间(必须调用,否则会抛出异常)

        xmlPullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);

        // Returns the type of the current event (START_TAG, END_TAG, TEXT,

        // etc.)

        int eventType = xmlPullParser.getEventType();

        while (eventType != XmlPullParser.END_DOCUMENT) {

            switch (eventType) {

                //开始节点<xxx>

                case XmlPullParser.START_TAG:

                    String tag = xmlPullParser.getName();

                    //Log.d(T, "START_TAG:" + tag);

                    if (tag.equalsIgnoreCase(riverStr)) {

                        river = new River();

                        river.setName(xmlPullParser.getAttributeValue(null, nameStr));

                        river.setLength(Integer.parseInt(xmlPullParser.getAttributeValue(null,

                                lengthStr)));

                    } else if (river != null) {

                        if (tag.equalsIgnoreCase(introductionStr)) {

                            river.setIntroduction(xmlPullParser.nextText());

                        } else if (tag.equalsIgnoreCase(imageurlStr)) {

                            river.setImageurl(xmlPullParser.nextText());

                        }

                    }

                    break;

                    //结束节点</xx>

                case XmlPullParser.END_TAG:

                    //Log.d(T, "END_TAG:" + xmlPullParser.getName());

                    if (xmlPullParser.getName().equalsIgnoreCase(riverStr) && river != null) {

                        rivers.add(river);

                        river = null;

                    }

                    break;

                default:

                    break;

            }

            eventType = xmlPullParser.next();

        }

    } catch (XmlPullParserException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    }

    Log.d(T, "exec fetchRiverFormXmlByPull use time = "

            + (System.currentTimeMillis() - startTime));

    return rivers;

}


本文转载自:http://my.eoe.cn/fengs/archive/20510.html

枫兮兮
粉丝 10
博文 72
码字总数 27211
作品 0
成都
私信 提问
Android 创建与解析XML(一)—— 概述

Android 是最常用的智能手机平台,XML 是数据交换的标准媒介,Android 中可以使用标准的XML生成器、解析器、转换器 API,对 XML 进行解析和转换。 XML,相关有DOM、SAX、JDOM、DOM4J、Xerce...

长平狐
2013/01/06
159
0
Android 创建与解析XML(六)—— 比较与使用

前面介绍了四种创建、解析XML的方式: 0、 Android 创建与解析XML(一)—— 概述 1、 Android 创建与解析XML(二)—— Dom方式 2、 Android 创建与解析XML(三)—— Sax方式 3、 Android ...

长平狐
2013/01/06
1K
0
Android读写XML(上)

注明:本文转自http://www.moandroid.com. 原文地址: http://www.moandroid.com/?p=508 XML 经常用作 Internet 上的一种数据格式,其文件格式想必大家都比较清楚,在这里我结合Android平台,...

晨曦之光
2012/03/01
391
0
android 中xml解析方式

XML在各种开发中都广泛应用,Android也不例外。作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能。今天就由我向大家介绍一下在Android平台下几种常见的XML解析和创建...

指尖上的开源
2015/01/19
0
0
SVG前戏—让你的View多姿多彩

什么是SVG SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形。是一种基于可扩展标记语言(XML)。它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质量下降。它的优点在于...

codeGoogle
2018/08/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

recv send 的 MSG_DONTWAIT 、 MSG_WAITALL 参数

基本概念: 阻塞IO:: socket 的阻塞模式意味着必须要做完IO 操作(包括错误)才会返回。 非阻塞IO:: 非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功。 ...

shzwork
30分钟前
2
0
怎么给开源项目提PR?

1. Fork 你想要提交 PR 的项目 2. 下载到本地 相关步骤如下: 在你需要的文件夹下面,右键使用 git bash 命令,打开 git 命令框 执行如下指令可将项目代码下载到当前目录 1代码仓库地址为示例...

xiaomin0322
33分钟前
2
0
浅复制与深复制概念

1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制...

GodIsCj
33分钟前
1
0
如何在工作中快速成长?致工程师的10个简单技巧

阿里妹导读:阿里有句非常经典的土话,“今天的最好表现,是明天的最低要求。”如何挖掘潜能、发现更好的自己?今天,阿里巴巴高级无线开发专家江建明将认知升级的方法总结出来,帮助你获得快...

阿里云官方博客
56分钟前
2
0
如何 SSH 到 Linux 服务器里的特定目录及执行命令?

这种操作对于新手来讲特别常见,良许之前也是这样。在本文,老司机将带你来进行更高效的操作,只需一步即可达到你想要的效果。 而且,不仅仅是实现快速进入到 Linux 服务器特定的目录,还可以...

架构师springboot
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部