详解android解析Xml的三种方式——DOM、SAX以及XMLpull

今天学习了android解析Xml的三种方式——DOM、SAX以及XMLpull,这里对它们进行总结。

 

如果理解有误,欢迎指正   ^_*

一、DOM方式解析:

xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。要是数据过大,手机不够牛逼,可能手机直接死机。

常用的DoM接口和类:

Document:该接口定义分析并创建DOM文档的一系列方法,它是文档树的根,是操作DOM的基础。
Element:该接口继承Node接口,提供了获取、修改XML元素名字和属性的方法。
Node:该接口提供处理并获取节点和子节点值的方法。
NodeList:提供获得节点个数和当前节点的方法。这样就可以迭代地访问各个节点。
DOMParser:该类是Apache的Xerces中的DOM解析器类,可直接解析XML文件。

二、SAX解析技术:

SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

常用的接口和类:

Attrbutes:用于得到属性的个数、名字和值。
DefaultHandler:它提供了这些接LI的缺省实现。在大多数情况下,为应用程序扩展DefaultHandler并覆盖相关的方法

三、XMLPull

XML pull提供了开始元素和结束元素。当某个元素开始时,我们可以调用parser.nextText0从XML文档中提取所有字符数据。当解释到一个文档结束时,自动生成EndDocument
事件。

常用的接口和类:

XmlPullParser:XML pull解析器是一个在XMLPULL VlAP1中提供了定义解析功能的接口。
XmlSerializer:它是一个接口,定义了XML信息集的序列。
XmlPullParserFactory:这个类用于在XMPULL V1 API中创建XML Pull解析器。

 

以下是源码:

写了一个解析接口然后分别用三个类来实现。当然还可以写成工具类的方式。

MainActivity:

package cn.yj3g.TL23_xml_test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.SimpleAdapter;
import cn.yj3g.entity.Person;
import cn.yj3g.service2.DomParseService;
import cn.yj3g.service2.PullParseService;
import cn.yj3g.service2.SAXParseService;

public class TL23_xml_testActivity extends ListActivity implements
        OnClickListener
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViewById(R.id.btn_dom).setOnClickListener(this);
        findViewById(R.id.btn_sax).setOnClickListener(this);
        findViewById(R.id.btn_pull).setOnClickListener(this);
    }

    public void onClick(View v)
    {
        int id = v.getId();
        List<Person> list = null;
        InputStream is = null;
        AssetManager manager = getAssets();
        try
        {
            is = manager.open("persons.xml");
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        switch (id)
        {
        case R.id.btn_dom:
            try
            {
                list = new DomParseService().getPersonsByParseXml(is);
                showUI(list);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
            break;
        case R.id.btn_sax:
            try
            {
                list = new SAXParseService().getPersonsByParseXml(is);
                showUI(list);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
            break;
        case R.id.btn_pull:
            try
            {
                Log.v("TAG", "btn_pull");
                list = new PullParseService().getPersonsByParseXml(is);
                showUI(list);
                Log.v("TAG", list.size() + "");
            } catch (Exception e)
            {
                e.printStackTrace();
            }
            break;
        default:
            break;
        }
        try
        {

            is.close();
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void showUI(List<Person> list)
    {
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
        for (Person p : list)
        {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", p.getId());
            map.put("name", p.getName());
            map.put("age", p.getAge());
            data.add(map);
        }
        String[] from =
        { "id", "name", "age" };
        int[] to =
        { R.id.tv_id, R.id.tv_name, R.id.tv_age };
        SimpleAdapter adapter = new SimpleAdapter(this, data,
                R.layout.person_list_item, from, to);
        setListAdapter(adapter);
    }
}

接口:

package cn.yj3g.service2;

import java.io.InputStream;
import java.util.List;

import cn.yj3g.entity.Person;

public interface IXmlParseService {

    public List<Person> getPersonsByParseXml(InputStream is) throws Exception;
}

DOM实现类:

package cn.yj3g.service2;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cn.yj3g.entity.Person;

public class DomParseService implements IXmlParseService
{

    @Override
    public List<Person> getPersonsByParseXml(InputStream is) throws Exception
    {
        List<Person> list = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(is);
        Element rootElement = document.getDocumentElement();
        NodeList nodeList = rootElement.getElementsByTagName("person");// 得到person节点链表
        if (nodeList == null || nodeList.getLength() == 0)
        {
            return null;
        }
        list = new ArrayList<Person>();
        for (int i = 0; i < nodeList.getLength(); i++)
        {
            Person person = new Person();
            Element element = (Element) nodeList.item(i);

            // 得到根节点属性:id
            int id = Integer.parseInt(element.getAttribute("id"));
            person.setId(id);

            // 得到孩子节点:name
            NodeList nameList = element.getElementsByTagName("name");
            Element nameElement = (Element) nameList.item(0);
            String name = nameElement.getTextContent();
            person.setName(name);

            // 得到年龄:age
            NodeList ageList = element.getElementsByTagName("age");
            Element ageElement = (Element) ageList.item(0);
            String age = ageElement.getTextContent();
            person.setAge(Integer.parseInt(age));

            list.add(person);

        }

        return list;
    }
}

SAX实现类:

package cn.yj3g.service2;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import cn.yj3g.entity.Person;

public class SAXParseService implements IXmlParseService
{

    public List<Person> getPersonsByParseXml(InputStream is) throws Exception
    {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        MyHandler handler = new MyHandler();
        parser.parse(is, handler);
        return handler.getList();
    }

    private class MyHandler extends DefaultHandler
    {
        private List<Person> list;
        private Person person;
        private String currentTag;

        private List<Person> getList()
        {
            return list;
        }

        @Override
        public void startDocument() throws SAXException
        {
            list = new ArrayList<Person>();
        }

        @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 = new Person();
                person.setId(Integer.parseInt(attributes.getValue("id")));
            } else if ("name".equals(qName) || "age".equals(qName))
            {
                currentTag = qName;
            }
        }

        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException
        {
            super.characters(ch, start, length);
            String s = new String(ch, start, length);
            if ("name".equals(currentTag))
            {
                person.setName(s);
            } else if ("age".equals(currentTag))
            {
                person.setId(Integer.parseInt(s));
            }
            currentTag = null;
        }

        @Override
        public void endElement(String uri, String localName, String qName)
        {
            if ("person".equals(qName))
            {
                list.add(person);
                person = null;
            }

        }

    }

}

Pull实现类:

package cn.yj3g.service2;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;
import cn.yj3g.entity.Person;

public class PullParseService implements IXmlParseService
{

    public List<Person> getPersonsByParseXml(InputStream is) throws Exception
    {

        List<Person> list = null;
        Person person = null;
        String currentTag = null;

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = factory.newPullParser();
        parser.setInput(is, "utf-8");
        int type = parser.getEventType();
        while (type != XmlPullParser.END_DOCUMENT)
        {
            String typeName = parser.getName();
            if (type == XmlPullParser.START_TAG)
            {
                Log.v("TAG", "typeName=" + typeName);
                if ("persons".equals(typeName))
                {
                    list = new ArrayList<Person>();
                } else if ("person".equals(typeName))
                {
                    person = new Person();
                    int id = Integer.parseInt(parser.getAttributeValue(0));
                    person.setId(id);
                } else if ("name".equals(typeName))
                {
                    currentTag = "name";
                } else if ("age".equals(typeName))
                {
                    currentTag = "age";
                }
            } else if (type == XmlPullParser.END_TAG)
            {
                if ("person".equals(typeName))
                {
                    list.add(person);
                    person = null;
                }
            } else if (type == XmlPullParser.TEXT)
            {
                String s = parser.getText();
                if ("name".equals(currentTag))
                {
                    person.setName(s);
                    currentTag = null;
                } else if ("age".equals(currentTag))
                {
                    person.setAge(Integer.parseInt(s));
                    currentTag = null;
                }
            }
            type = parser.next();
        }
        Log.v("TAG", "size=" + list.size());
        return list;
    }
}

Person测试类:

package cn.yj3g.entity;

public class Person {

    private int id;
    private String name;
    private int age;

    public Person(int id, String name, int age) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Person() {
        super();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
}

要读取的Person  XML文件:

<?xml version="1.0" encoding="utf-8"?>
<persons>
    <person id="1">
        <name>刘备</name>
        <age>12</age>    
    </person>
    <person id="2">
        <name>关羽</name>
        <age>14</age>    
    </person>
    <person id="3">
        <name>张飞</name>
        <age>15</age>    
    </person>
</persons>

附源码下载地址:http://download.csdn.net/detail/badboy1110/3629850

 

不要资源分,希望大家能有收获。  ^_*

 

如果觉得有帮助,顺手给我个评论~~~~多谢~

posted on 2014-10-27 18:09  大有@  阅读(256)  评论(0编辑  收藏  举报

导航