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

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;

}


你可能感兴趣的:([Android] android平台下sax,dom,pull解析方式性能比较)