Android网络编程之XML解析

来源:互联网 发布:mac口红免税店价格 编辑:程序博客网 时间:2024/06/06 13:56

一.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 1
原创粉丝点击