原文链接:http://www.orlion.ga/685/

解析XML常用的方式有两种,一种是PULL解析一种是SAX解析。

假设解析数据为:

<apps>
    <app>
        <id>1</id>
        <name>Google Maps</name>
        <version>1.0</version>
    </app>
    <app>
        <id>2</id>
        <name>Chrome</name>
        <version>2.1</version>
    </app>
    <app>
        <id>3</id>
        <name>Google Play</name>
        <version>2.3</version>
    </app>
</apps>

一、PULL解析

try {
    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    XmlPullParser xmlPullParser = factory.newPullParser();
    xmlPullParser.setInput(new StringReader(xmlData));
    int eventType = xmlPullParser.getEventType();
    String id = "";
    String name = "";
    String version = "";
    while (eventType != XmlPullParser.END_DOCUMENT) {
        String nodeName = xmlPullParser.getName();
        switch (eventType) {
        // 开始解析某个结点
        case XmlPullParser.START_TAG: {
            if ("id".equals(nodeName)) {
                id = xmlPullParser.nextText();
            } else if ("name".equals(nodeName)) {
                name = xmlPullParser.nextText();
            } else if ("version".equals(nodeName)) {
                version = xmlPullParser.nextText();
            }
            break;
        }
        // 完成解析某个结点
        case XmlPullParser.END_TAG: {
            if ("app".equals(nodeName)) {
                Log.d("MainActivity", "id is " + id);
                Log.d("MainActivity", "name is " + name);
                Log.d("MainActivity", "version is " + version);
            }
            break;
        }
        default:
            break;
        }
        eventType = xmlPullParser.next();
    }
} catch (Exception e) {
    e.printStackTrace();
}

首先要获取到一个XmlPullParserFactory 的实例,并借助这个实例得到 XmlPullParser 对象,然后调用XmlPullParser的 setInput()方法将服务器返回的 XML数据设置进去就可以开始解析了。解析的过程也是非常简单,通过 getEventType()可以得到当前的解析事件,然后在一个 while循环中不断地进行解析,如果当前的解析事件不等于 XmlPullParser.END_DOCUMENT,说明解

析工作还没完成,调用 next()方法后可以获取下一个解析事件。在 while循环中,我们通过 getName()方法得到当前结点的名字,如果发现结点名等于id、name或 version,就调用 nextText()方法来获取结点内具体的内容,每当解析完一个 app

结点后就将获取到的内容打印出来。

二、SAX解析方式

新建一个 ContentHandler类继承自 DefaultHandler,并重写父类的五个方法,如下所示:

public class ContentHandler extends DefaultHandler {
    private String nodeName;
    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder version;
    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
    }
    @Override
    public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
        // 记录当前结点名
        nodeName = localName;
    }
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // 根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
        if ("id".equals(nodeName)) {
            id.append(ch, start, length);
        } else if ("name".equals(nodeName)) {
            name.append(ch, start, length);
        } else if ("version".equals(nodeName)) {
            version.append(ch, start, length);
        }
    }
    @Override
    public void endElement(String uri, String localName, String qName) throwsSAXException {
        if ("app".equals(localName)) {
            Log.d("ContentHandler", "id is " + id.toString().trim());
            Log.d("ContentHandler", "name is " + name.toString().trim());
            Log.d("ContentHandler", "version is " + version.toString().trim());
            // 最后要将StringBuilder清空掉
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }
    @Override
    public void endDocument() throws SAXException {
    }
}

可以看到,我们首先给 id、name和 version结点分别定义了一个 StringBuilder对象,并在 startDocument()方法里对它们进行了初始化。 每当开始解析某个结点的时候, startElement()方法就会得到调用,其中 localName参数记录着当前结点的名字,这里我们把它记录下来。接着在解析结点中具体内容的时候就会调用 characters()方法, 我们会根据当前的结点名进行判断,将解析出的内容添加到哪一个 StringBuilder对象中。最后在 endElement()方法中进行判断,如果 app结点已经解析完成,就打印出 id、name和 version的内容。需要注意的是,目前id、name和 version中都可能是包括回车或换行符的,因此在打印之前我们还需要调用一下 trim()方法,并且打印完成后还要将 StringBuilder的内容清空掉,不然的话会影响下一次内容的读取

解析XML:

try {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    XMLReader xmlReader = factory.newSAXParser().getXMLReader();
    ContentHandler handler = new ContentHandler();
    // 将ContentHandler的实例设置到XMLReader中
    xmlReader.setContentHandler(handler);
    // 开始执行解析
    xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
    e.printStackTrace();
}

调用 parseXMLWithSAX()方法来解析 XML数据。parseXMLWithSAX()方法中先是创建了一个 SAXParserFactory的对象,然后再获取到XMLReader对象,接着将我们编写的 ContentHandler的实例设置到 XMLReader中,最后调用 parse()方法开始执行解析就好了。

 

Android入门(二十一)解析XML的更多相关文章

  1. Android之使用XMLPull解析xml(二)

    转自:http://www.blogjava.net/sxyx2008/archive/2010/08/04/327885.html 介绍下在Android中极力推荐的xmlpull方式解析xml.x ...

  2. Java从零开始学四十二(DOM解析XML)

    一.DOM解析XML xml文件 favorite.xml <?xml version="1.0" encoding="UTF-8" standalone ...

  3. Android 使用pull,sax解析xml

    pull解析xml文件 1.获得XmlpullParser类的引用 这里有两种方法 //解析器工厂 XmlPullParserFactory factory=XmlPullParserFactory. ...

  4. Android 生成和Pull解析xml

    一.单个对象生成xml 生成以下xml,该怎么生成呢? <?xml version='1.0' encoding='UTF-8' standalone='yes' ?> <accou ...

  5. android 67 生成和解析xml

    生成xml: package com.itheima.createxml; import java.io.File; import java.io.FileNotFoundException; imp ...

  6. android 生成、pull解析xml文件

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...

  7. Android中三种常用解析XML的方式(DOM、SAX、PULL)简介及区别

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

  8. Android入门(二十二)解析JSON

    原文链接:http://www.orlion.ga/687/ 解析JSON的方式有很多,主要有官方提供的 JSONObject,谷歌的开源库 GSON.另外,一些第三方的开源库如 Jackson.Fa ...

  9. Android入门(二)Activity-Toast、Intent

    原文链接:http://www.orlion.ga/427/ 一.隐藏activity的标题 在activity的java代码的onCreate()方法中入requestWindowFeature(W ...

随机推荐

  1. 亲临现场不是梦,2017央视春晚推出VR直播

    自里约奥运会首次试水VR直播 后,用户开始关注这种观影方式,一瞬间VR直播开始流行.就在月初,江苏卫视宣布2017年跨年晚会将进行VR全景直播.当然,央视是绝对不会错过这中潮流方式. 据悉,央视201 ...

  2. 洛谷 P2726 阶乘 Factorials Label:Water

    题目背景 N的阶乘写作N!,表示小于等于N的所有正整数的乘积. 题目描述 阶乘会变大得很快,如13!就必须用32位整数类型来存储,到了70!即使用浮点数也存不下了. 你的任务是找到阶乘最前面的非零位. ...

  3. fatal error

    1.   fatal error C1083: 无法打开源文件 编译报此错误:  1>c1xx : fatal error C1083: 无法打开源文件:“Projects\XXXCCCC\VB ...

  4. spring3.0使用annotation完全代替XML

    @Service与@Component有什么不同?那天被问到这个问题,一时之间却想不起来,就利用这篇文章来纪录spring3.0中常用的annotation. 从spring2.5开始,annotat ...

  5. 简单C#、asp.net mvc验证码的实现

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text;u ...

  6. java-JDBC配置驱动程序

    我们以常用的3种数据库为例. MySQL数据库 驱动程序包名:mysql-connector-java-3.1.11-bin.jar 驱动类的名字:com.mysql.jdbc.Driver JDBC ...

  7. Handlebars.js的学习

    写在开头的话: 在使用Ghost搭建自己的博客的时候,发现不会Handlebars.js寸步难行,所以本人决定学习下Handlebars.js,因此在此做个记录 为什么选择Handlebars.js ...

  8. Xcode 调试技巧

    一 NSLog调试 官方文档:Logs an error message to the Apple System Log facility. 即NSLog不是作为普通的debug log的,而是err ...

  9. 如何修改SQL SERVER服务器的端口

    sql server的服务器端口默认是1433,设置服务器端口的位置在这里: 这里的端口,默认是1433,我把它改成了65499 修改端口之后,客户端如何连接? 下面是SSMS的连接方式: 下面是一个 ...

  10. Android ANR 分析解决方法

    一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1. KeyDispatchTimeout(5 seconds) ...