Android网络编程之XML解析

一.XML的概念

  • XML是一种用于标记电子文件使其具有结构性的标记语言。
  • XML的设计宗旨是传输数据,而不是显示数据。
  • XML是各种应用程序之间进行数据传输的最常用的工具。

二.XML的语法

  • 任何的起始标签都必须有一个结束标签。
  • 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<Android/>。XML解析器会将其翻译成<Android></Android>
  • 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
  • 所有的特性都必须有值。
  • 所有的特性都必须在值的周围加上双引号。

XML示例:

<note>
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
</note>

三.解析XML的常用方法及优缺点

下面提供一个天气获取网址:获取天气XML,下面将用这个网址提供的XML数据来编写示例代码。

准备工作:
1)获取天气XML数据输入流

别忘了添加网络访问权限:

 <uses-permission android:name="android.permission.INTERNET"/>

获取数据使用的异步任务:

    /**
     * 异步任务
     * 获取XML数据,并解析XML
     */
    class WeatherTask extends AsyncTask<URL, Void, List<City>> {

        @Override
        protected List<City> doInBackground(URL... params) {
            //获取XML数据的输入流
            try {
                HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                InputStream is =  conn.getInputStream();
                //开始解析XML
                SaxWeatherParser swp = new SaxWeatherParser();
                return swp.parse(is);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(List<City> cities) {
            super.onPostExecute(cities);
            //最终数据,这里仅作打印操作。
            if (cities != null) {
                Log.i("TAG", cities.toString());
            }
        }
    }

2)创建天气实体类City

package xml.example.com.xmltest;

/**
 * Created by Zz on 2015/9/11.
 */
public class City {
    private String quName;
    private String pyName;
    private String cityname;
    private String state1;
    private String state2;
    private String stateDetailed;
    private String tem1;
    private String tem2;
    private String windState;

    public String getQuName() {
        return quName;
    }

    public void setQuName(String quName) {
        this.quName = quName;
    }

    public String getPyName() {
        return pyName;
    }

    public void setPyName(String pyName) {
        this.pyName = pyName;
    }

    public String getCityname() {
        return cityname;
    }

    public void setCityname(String cityname) {
        this.cityname = cityname;
    }

    public String getState1() {
        return state1;
    }

    public void setState1(String state1) {
        this.state1 = state1;
    }

    public String getState2() {
        return state2;
    }

    public void setState2(String state2) {
        this.state2 = state2;
    }

    public String getStateDetailed() {
        return stateDetailed;
    }

    public void setStateDetailed(String stateDetailed) {
        this.stateDetailed = stateDetailed;
    }

    public String getTem1() {
        return tem1;
    }

    public void setTem1(String tem1) {
        this.tem1 = tem1;
    }

    public String getTem2() {
        return tem2;
    }

    public void setTem2(String tem2) {
        this.tem2 = tem2;
    }

    public String getWindState() {
        return windState;
    }

    public void setWindState(String windState) {
        this.windState = windState;
    }

    @Override
    public String toString() {
        return "City{" +
                "quName='" + quName + '\'' +
                ", pyName='" + pyName + '\'' +
                ", cityname='" + cityname + '\'' +
                ", state1='" + state1 + '\'' +
                ", state2='" + state2 + '\'' +
                ", stateDetailed='" + stateDetailed + '\'' +
                ", tem1='" + tem1 + '\'' +
                ", tem2='" + tem2 + '\'' +
                ", windState='" + windState + '\'' +
                '}';
    }
}

Android中常用的四种XML解析方法:

1. SAX解析器

  • 原理
    SAX解析器是基于事件驱动的。他将XML文档转化为一系列的事件,然后由事件处理器来决定如何处理。这种模式主要是基于事件源和事件处理器的。
    (能产生事件的对象是事件源,对事件做出响应处理的对象被叫做事件处理器)

  • 步骤
    1)获取SAXParserFactory实例对象

    2)获取SAXParser实例对象

    3)写一个handler继承DefaultHandler

    5)把传入的InputStream和自己写的handler注册到SAXParser中

    6)正式开始解析

2. DOM解析器

  • 原理:
    DOM解析器把整个XML文件全部加载到内存中,在内存中形成一个与XML文件结构相对应的节点树。特点:占用资源多,效率高。

  • 步骤:
    1)获取DocumentBuilderFactory的实例对象

    2)获取DocumentBuilder的实例对象

    3)获取Document的实例对象

    4)获取Element的实例对象

    5)获取所有节点NodeList

    6)遍历并解析节点

准备工作同上,只需要修改异步任务中的解析部分。
将如下代码:

                SAXWeatherParser swp = new SAXWeatherParser();
                return swp.parse(is);

改为:

                DOMWeatherParser dwp = new DOMWeatherParser();
                return dwp.parse(is);

3. PULL解析器

  • 原理:
    Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。

  • 步骤:
    1)获取XmlPullParserFactory实例对象
    2)获取XmlPullParser 实例对象
    3)设置输入流和编码
    4)获取事件类型
    5)根据事件类型循环解析

准备工作同上,只需要修改异步任务中的解析部分。
将如下代码:

                DOMWeatherParser dwp = new DOMWeatherParser();
                return dwp.parse(is);

改为:

                PULLWeatherParser pwp = new PULLWeatherParser();
                return pwp.parse(is);

4.Dom4j解析框架

Dom4j.jar官方下载地址:http://sourceforge.net/projects/dom4j/files/
dom4j1.6.1.jar百度云下载地址:dom4j1.6.1下载

  • 简介:
    Dom4j是dom4j.org出品的一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。

  • 步骤:
    这里主要介绍String转Java bean用法,其他用法参见官方文档。这里提供一个1.6.1版本的文档下载链接:dom4j-1.6.1 docs

1)获取SAXReader实例对象
2)获取Document实例对象
3)获取Element的实例对象
4)获取所有节点NodeList
5)遍历并解析节点

可见, 和DOM解析器步骤相似。

准备工作同上,修改异步任务如下:

                PULLWeatherParser pwp = new PULLWeatherParser();
                return pwp.parse(is);

改为

                Dom4jWeatherParser d4wp = new Dom4jWeatherParser();
                return d4wp.parse(is);

四.使用SAX解析XML

SAX解析代码如下:

package xml.example.com.xmltest;

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

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

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

/**
 * Created by Zz on 2015/9/11.
 */
public class SAXWeatherParser {

    /**
     * 解析过程
     * @param is 输入流
     * @return 集合
     */
    public List<City> parse(InputStream is) throws Exception{
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        WeatherHandler handler = new WeatherHandler();
        parser.parse(is, handler);
        is.close();
        return handler.getCities();
    }

    /**
     * 继承DefaultHandler,具体解析方式都在这里面。
     * 需要实现5个最重要的方法。
     */
    private class WeatherHandler extends DefaultHandler {

        private List<City> cities;
        private City city;
        //此处不需要tagName,这个是为characters方法使用的。
        private String tagName;


        /**
         * 返回解析后各城市天气集合
         * @return 集合
         */
        public List<City> getCities() {
            return cities;
        }

        //接收文档开始的通知。当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            //初始化集合
            cities = new ArrayList<City>();
        }

        //接收元素开始的通知。当遇到元素的开头的时候,调用这个方法。
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            if (localName.equals("city")) {
                city = new City();
                //根据属性值获取数据
                city.setQuName(attributes.getValue("quName"));
                city.setPyName(attributes.getValue("pyName"));
                city.setCityname(attributes.getValue("cityname"));
                city.setState1(attributes.getValue("state1"));
                city.setState2(attributes.getValue("state2"));
                city.setStateDetailed(attributes.getValue("stateDetailed"));
                city.setTem1(attributes.getValue("tem1"));
                city.setTem2(attributes.getValue("tem2"));
                city.setWindState(attributes.getValue("windState"));
            }
            tagName = localName;
        }

        //接收字符数据的通知。当遇到字符数据的时候,调用这个方法。如<string>hello</string>中的hello就是字符数据。
        //本例中不需要使用此方法。因为没有上述字符数据。
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);
        }

        //接收元素结尾的通知。当遇到元素结尾的时候,调用这个方法。
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName);
            if (localName.equals("city")) {
                cities.add(city);
                city = null;
            }
            this.tagName = null;
        }

        //接收文档结尾的通知。当遇到文档结尾的时候,调用这个方法。一般可以不用写。这里仅作说明用。
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }
    }

}

调用代码在MainActivity实现如下:

    private List<City> cities;

    private static final String WEATHER_URL = "http://flash.weather.com.cn/wmaps/xml/china.xml";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //启动异步任务,开始获取数据并解析数据
        try {
            new WeatherTask().execute(new URL(WEATHER_URL));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

解析结果如下

09-11 12:53:06.923  31095-31095/xml.example.com.xmltest I/TAG[City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='9', windState='北风4-5级转3-4级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='9', windState='北风转西北风3-4级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='1', state2='1', stateDetailed='多云', tem1='24', tem2='11', windState='北风3-4级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='32', tem2='25', windState='东风3-4级'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='0', stateDetailed='多云转晴', tem1='16', tem2='5', windState='西北风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='26', tem2='18', windState='东南风6-7级'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='7', stateDetailed='阴转小雨', tem1='23', tem2='11', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='15', tem2='4', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='7', windState='北风4-5级转微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='1', state2='0', stateDetailed='多云转晴', tem1='20', tem2='9', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='15', windState='西北风3-4级转4-5级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='2', state2='1', stateDetailed='阴转多云', tem1='24', tem2='16', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='27', tem2='19', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='31', tem2='22', windState='北风小于3级'}, City{quName='山东', pyName='shandong', cityname='济南', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='20', tem2='14', windState='北风小于3级转3-4级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='2', state2='2', stateDetailed='阴', tem1='27', tem2='20', windState='东北风小于3级转北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='28', tem2='20', windState='北风小于3级转3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='9', windState='西北风4-5级转3-4级'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='1', state2='0', stateDetailed='多云转晴', tem1='26', tem2='15', windState='东北风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='25', tem2='19', windState='南风小于3级'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='1', state2='9', stateDetailed='多云转大雨', tem1='25', tem2='15', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='3', state2='3', stateDetailed='阵雨', tem1='23', tem2='16', windState='东南风转东北风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='0', state2='1', stateDetailed='晴转多云', tem1='29', tem2='20', windState='东北风小于3级转3-4级'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='1', stateDetailed='多云', tem1='31', tem2='22', windState='东风3-4级转微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='0', state2='1', stat

(注:由于Log信息太长,且未换行,未能显示完整。实际上已经全部解析出来了。)

五.使用DOM解析XML

DOM解析代码如下

package xml.example.com.xmltest;

import android.util.Log;

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

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

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

/**
 * Created by Zz on 2015/9/11.
 */
public class DOMWeatherParser {

    /**
     * 解析过程
     * @param is 输入流
     * @return 集合
     * @throws Exception 异常
     */
    public List<City> parse(InputStream is) throws Exception{
        List<City> cities = new ArrayList<City>();

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(is);
        Element element = document.getDocumentElement();
        //得到所有city节点
        NodeList items = element.getElementsByTagName("city");
        //遍历city节点
        for (int i=0; i<items.getLength();i++) {
            City city = new City();
            //得到第一个city节点
            Element item = (Element) items.item(i);

            //获取节点的属性值
            city.setQuName(item.getAttribute("quName"));
            city.setPyName(item.getAttribute("pyName"));
            city.setCityname(item.getAttribute("cityname"));
            city.setState1(item.getAttribute("state1"));
            city.setState2(item.getAttribute("state2"));
            city.setStateDetailed(item.getAttribute("stateDetailed"));
            city.setTem1(item.getAttribute("tem1"));
            city.setTem2(item.getAttribute("tem2"));
            city.setWindState(item.getAttribute("windState"));

            //将节点添加到集合
            cities.add(city);
        }
        return cities;
    }

}

解析结果如下

09-11 14:18:59.333  19643-19643/xml.example.com.xmltest I/TAG﹕ [City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='9', windState='北风4-5级转3-4级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='9', windState='北风转西北风3-4级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='1', state2='1', stateDetailed='多云', tem1='24', tem2='11', windState='北风3-4级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='32', tem2='25', windState='东风3-4级'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='0', stateDetailed='多云转晴', tem1='16', tem2='5', windState='西北风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='26', tem2='18', windState='东南风6-7级'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='7', stateDetailed='阴转小雨', tem1='23', tem2='11', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='15', tem2='4', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='7', windState='北风4-5级转微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='1', state2='0', stateDetailed='多云转晴', tem1='20', tem2='9', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='15', windState='西北风3-4级转4-5级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='2', state2='1', stateDetailed='阴转多云', tem1='24', tem2='16', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='27', tem2='19', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='31', tem2='22', windState='北风小于3级'}, City{quName='山东', pyName='shandong', cityname='济南', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='20', tem2='14', windState='北风小于3级转3-4级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='2', state2='2', stateDetailed='阴', tem1='27', tem2='20', windState='东北风小于3级转北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='28', tem2='20', windState='北风小于3级转3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='9', windState='西北风4-5级转3-4级'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='1', state2='0', stateDetailed='多云转晴', tem1='26', tem2='15', windState='东北风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='25', tem2='19', windState='南风小于3级'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='1', state2='9', stateDetailed='多云转大雨', tem1='25', tem2='15', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='3', state2='3', stateDetailed='阵雨', tem1='23', tem2='16', windState='东南风转东北风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='0', state2='1', stateDetailed='晴转多云', tem1='29', tem2='20', windState='东北风小于3级转3-4级'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='1', stateDetailed='多云', tem1='31', tem2='22', windState='东风3-4级转微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='0', state2='1', stat

六.使用PULL解析XML

PULL解析代码如下

package xml.example.com.xmltest;

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

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

/**
 * Created by Zz on 2015/9/11.
 */
public class PULLWeatherParser {


    public List<City> parse(InputStream is) throws Exception {

        List<City> cities = null;
        City city = null;

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = factory.newPullParser();
        parser.setInput(is, "UTF-8");

        int eventType = parser.getEventType();

        while (eventType != XmlPullParser.END_DOCUMENT) {
            switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    //初始化工作
                    cities = new ArrayList<City>();
                    break;
                case XmlPullParser.START_TAG:
                    String name = parser.getName();
                    if (name.equals("city")) {
                        city = new City();
                        city.setQuName(parser.getAttributeValue(null, "quName"));
                        city.setPyName(parser.getAttributeValue(null, "pyName"));
                        city.setCityname(parser.getAttributeValue(null, "cityname"));
                        city.setState1(parser.getAttributeValue(null, "state1"));
                        city.setState2(parser.getAttributeValue(null, "state2"));
                        city.setStateDetailed(parser.getAttributeValue(null, "stateDetailed"));
                        city.setTem1(parser.getAttributeValue(null, "tem1"));
                        city.setTem2(parser.getAttributeValue(null, "tem2"));
                        city.setWindState(parser.getAttributeValue(null, "windState"));
                    }
                    break;

                case XmlPullParser.END_TAG:
                    if (parser.getName().equals("city") && city != null && cities != null) {
                        //添加节点到集合
                        cities.add(city);
                    }
                    break;
            }
            //下一个节点
            eventType = parser.next();
        }

        return cities;
    }

}

解析结果如下

09-11 15:32:00.202  12176-12176/xml.example.com.xmltest I/TAG[City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='9', windState='北风4-5级转3-4级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='9', windState='北风转西北风3-4级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='1', state2='1', stateDetailed='多云', tem1='24', tem2='11', windState='北风3-4级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='32', tem2='25', windState='东风3-4级'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='0', stateDetailed='多云转晴', tem1='16', tem2='5', windState='西北风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='26', tem2='18', windState='东南风6-7级'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='7', stateDetailed='阴转小雨', tem1='23', tem2='11', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='15', tem2='4', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='7', windState='北风4-5级转微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='1', state2='0', stateDetailed='多云转晴', tem1='20', tem2='9', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='15', windState='西北风3-4级转4-5级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='2', state2='1', stateDetailed='阴转多云', tem1='24', tem2='16', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='27', tem2='19', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='31', tem2='22', windState='北风小于3级'}, City{quName='山东', pyName='shandong', cityname='济南', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='20', tem2='14', windState='北风小于3级转3-4级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='2', state2='2', stateDetailed='阴', tem1='27', tem2='20', windState='东北风小于3级转北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='28', tem2='20', windState='北风小于3级转3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='9', windState='西北风4-5级转3-4级'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='1', state2='0', stateDetailed='多云转晴', tem1='26', tem2='15', windState='东北风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='25', tem2='19', windState='南风小于3级'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='1', state2='9', stateDetailed='多云转大雨', tem1='25', tem2='15', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='3', state2='3', stateDetailed='阵雨', tem1='23', tem2='16', windState='东南风转东北风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='0', state2='1', stateDetailed='晴转多云', tem1='29', tem2='20', windState='东北风小于3级转3-4级'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='1', stateDetailed='多云', tem1='31', tem2='22', windState='东风3-4级转微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='0', state2='1', stat

七.使用Dom4j解析XML

Dom4j解析代码如下:

package xml.example.com.xmltest;

import android.util.Log;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

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

/**
 * Created by Zz on 2015/9/23.
 */
public class Dom4jWeatherParser {

    /**
     * 解析过程
     * @param is 输入流
     * @return 集合
     * @throws Exception 异常
     */
    @SuppressWarnings("unchecked")
    public List<City> parse(InputStream is) throws Exception {
        List<City> cities = new ArrayList<City>();
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(is);
        //获取根节点
        Element root = document.getRootElement();
        //获取子节点
        List<Element> elements = root.elements();
        for (int i =0 ;i < elements.size(); i++) {
            City city = new City();

            Element item = elements.get(i);
            //获取节点的属性值
            city.setQuName(item.attributeValue("quName"));
            city.setPyName(item.attributeValue("pyName"));
            city.setCityname(item.attributeValue("cityname"));
            city.setState1(item.attributeValue("state1"));
            city.setState2(item.attributeValue("state2"));
            city.setStateDetailed(item.attributeValue("stateDetailed"));
            city.setTem1(item.attributeValue("tem1"));
            city.setTem2(item.attributeValue("tem2"));
            city.setWindState(item.attributeValue("windState"));

            //将节点添加到集合
            cities.add(city);

        }

        return cities;
    }
}

Dom4j解析结果如下:

09-23 19:58:35.908      758-758/xml.example.com.xmltest I/TAG﹕ [City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='8', tem2='18', windState='东北风转东风小于3级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='9', tem2='21', windState='东北风小于3级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='12', tem2='25', windState='东北风转东南风小于3级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='25', tem2='33', windState='微风'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='1', stateDetailed='多云', tem1='8', tem2='19', windState='西风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='7', tem2='18', windState='微风'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='3', stateDetailed='阴转阵雨', tem1='11', tem2='22', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='5', tem2='15', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='2', state2='1', stateDetailed='阴转多云', tem1='10', tem2='21', windState='微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='7', state2='1', stateDetailed='小雨转多云', tem1='10', tem2='22', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='1', stateDetailed='多云', tem1='17', tem2='27', windState='微风转南风小于3级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='7', state2='7', stateDetailed='小雨', tem1='19', tem2='23', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='20', tem2='24', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='2', stateDetailed='多云转阴', tem1='22', tem2='31', windState='微风'}, City{quName='山东', pyName='shandong', cityname='济南', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='28', windState='南风小于3级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='1', state2='2', stateDetailed='多云转阴', tem1='20', tem2='27', windState='东北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='20', tem2='28', windState='东风小于3级转东北风3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='2', stateDetailed='多云转阴', tem1='12', tem2='25', windState='微风'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='21', state2='2', stateDetailed='小到中雨转阴', tem1='15', tem2='22', windState='东风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='19', tem2='23', windState='微风'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='3', state2='3', stateDetailed='阵雨', tem1='17', tem2='25', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='2', state2='3', stateDetailed='阴转阵雨', tem1='19', tem2='24', windState='南风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='2', state2='1', stateDetailed='阴转多云', tem1='20', tem2='28', windState='微风'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='24', tem2='31', windState='微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='1', state2='1', stateDetailed='多云', tem1='22', tem2='29', windState='微风'}, City{quName='广东', pyName='guangdong', cityname=

八.总结

四种解析器各有各的优缺点,那么使用的时候应该如何抉择呢?

首先总结一下四者的优缺点
1)SAX:一次性解析整个文档,不能中途停止。内存占用较少。解析速度快,但代码比较繁琐。

2)DOM:整个文件读入内存,所以较大的XML文件会占用大量内存。解析速度慢,但可以提取想要的内容。

3)PULL:可以通过程序控制在哪里停止解析。可控性强。内存占用较少。解析速度快,代码更简洁。

4)Dom4j:性能非常好,灵活性高,易使用。代码简介。

综上,Dom4j , SAX,PULL所占内存少,更适合移动设备的XML解析,如果硬要在Dom4j、SAX和PULL中抉择,我觉得Dom4j和PULL都可以。虽然DOM占用内存大,但这并不代表DOM就不能在Android设备上使用,在解析小文件且需要反复检索时,还是可以考虑使用DOM解析XML的。另外,Dom4j底层也是基于SAX和DOM的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值