Android XML文档简析

转载 2016年10月25日 18:07:04

转载:http://www.cnblogs.com/huhx/p/AndroidXmlParse.html


Pull解析的用法:

START_DOCUMENT 文档开始的标签 文档开始时,解析器没有任何数据

START_TAG 解析到标签开头

TEXT 解析到元素的内容

END_TAG 解析在标签末尾

END_DOCUMENT 文档结束,解析器不会再解析


PULL解析的步骤:


建立XML PuLL工厂实例

XmlPullParseFactory factory=XmlPullParseFactory.newInstance();

不指定命名空间,将使用默认的解析器,如果要改变命名空间,则使用setNamespaceAware()这个方法: 

factory.setNamespaceAware(true);

  创建一个解析的实例:

  XmlPullParse xpp=factory.newPullParse();

    解析输入的数据:

    xpp.setInput(new FileReader(filename));

  接下来就可以根据不同的事件,做不同额解析处理:一般用next()方法去得到下一个事件


next()方法与nextToken()方法

next()方法只能支持上述常用的五个事件

nextToken()方法不但支持next()方法的事件,还额外支持:COMMENT CDSECT DECDECL ENTITY_REF ROCESSING_INSTRUCTION, or IGNORABLE_WHITESPACE


我们在assets中创建一个文件:linux.xml

<span style="font-family:Courier New;font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<LOL>
    <person>
        <!-- 这里是盖伦的注释 -->
        <name sex="man">盖伦</name>
        <address>德玛西亚</address>
        <say>我将带头冲锋</say>
    </person>
    <person>
        <!-- 这里是亚索的注释 -->
        <name sex="man">亚索</name>
        <address>艾欧尼亚</address>
        <say>死亡如风,常伴吾身</say>
    </person>
    <person>
        <!-- 这里是瑞雯的注释 -->
        <name sex="girl">瑞雯</name>
        <address>诺克萨斯</address>
        <say>战争与谋杀之间,潜藏着我们的心魇</say>
    </person>
</LOL>
</span>

在MainActivity.java中定义一个方法,得到linux.xml文件的内容

<span style="font-family:Courier New;">// 得到xml的数据
private String getXMLData(String fileName) {
    StringBuffer stringBuffer = new StringBuffer();
    InputStream inputStream = null;
    BufferedReader bufferedReader = null;

    try {
        inputStream = getResources().getAssets().open(fileName);
        bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String line = "";
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line + "\n");
        }
        bufferedReader.close();
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    Log.i(TAG, stringBuffer.toString());
    return stringBuffer.toString();
}</span><span style="font-family:courier new, 微软雅黑, courier, sans-serif;">
</span>

定义一个方法,用PULL解析得到的数据:

<span style="font-family:Courier New;">// pull解析xml数据
public void pullParse(View view) {
    String xmlData = getXMLData(fileName);
    try {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser xmlPullParser = factory.newPullParser();
        xmlPullParser.setInput(new StringReader(xmlData));
        int eventType = xmlPullParser.getEventType();

        String name = "";
        String address = "";
        String say = "";
        String sex = "";

        while (eventType != XmlPullParser.END_DOCUMENT) {
            String nodeName = xmlPullParser.getName();
            switch (eventType) {
                case XmlPullParser.START_TAG: {
                    if ("name".equals(nodeName)) {
                        // sex与name的位置不能互换
              // sex = xmlPullParser.getAttributeValue(0);
                        sex = xmlPullParser.getAttributeValue(null, "sex");
                        name = xmlPullParser.nextText();
                    } else if ("address".equals(nodeName)) {
                        address = xmlPullParser.nextText();
                    } else if ("say".equals(nodeName)) {
                        say = xmlPullParser.nextText();
                    }
                    break;
                }
                // 完成解析某个结点
                case XmlPullParser.END_TAG: {
                    if ("person".equals(nodeName)) {
                        Log.d(TAG, "name: " + name);
                        Log.d(TAG, "address: " + address);
                        Log.d(TAG, "say: " + say);
                        Log.d(TAG, "sex: " + sex);
                    }
                    break;
                }
                default:
                    break;
            }
            eventType = xmlPullParser.next();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}</span>
若要解析到<!-- -->里面的注释内容,需要做以下的修改:增加case,修改next()方法为nextToken()方法:

<span style="font-family:Courier New;">// 增加一个case,用于接收注释的事件
case XmlPullParser.COMMENT: {
        coment = xmlPullParser.getText();
        break;
    }
    default:
        break;
}
eventType = xmlPullParser.nextToken();  // 此处为修改部分</span>

打印日志如下:(增加了注释的功能)

<span style="font-family:Courier New;">03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: name: 盖伦
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: address: 德玛西亚
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: say: 我将带头冲锋
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: sex: man
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: comment:  这里是盖伦的注释 
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: name: 亚索
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: address: 艾欧尼亚
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: say: 死亡如风,常伴吾身
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: sex: man
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: comment:  这里是亚索的注释 
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: name: 瑞雯
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: address: 诺克萨斯
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: say: 战争与谋杀之间,潜藏着我们的心魇
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: sex: girl
03-16 18:09:59.662 24745-24745/com.example.linux.xmlparsetest D/MainActivity: comment:  这里是瑞雯的注释 </span>

Sax解析的用法

一、 SAX解析的简要:

SAX:事件驱动型的XML解析方式。顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问,且是只读的。由于移动设备的内存资源有限,SAX的顺序读取方式更适合移动开发。

二、 SAX解析XML步骤:

  • 创建XML解析处理器。
  • 创建SAX解析器。
  • 将XML解析处理器分配给解析器。
  • 对文档进行解析,将每个事件发送给处理器。

三、SAX解析的过程:

  • 解析开始之前,需要向XMLReader注册一个ContentHandler,也就是相当于一个事件监听器,
  • 在ContentHandler中定义了很多方法,比如startDocument(),它定制了当在解析过程中,遇到文档开始时应该处理的事情。
  • 当 XMLReader读到合适的内容,就会抛出相应的事件,并把这个事件的处理权代理给ContentHandler,调用其相应的方法进行响应。


Sax解析的代码

<span style="font-family:Courier New;">package com.example.linux.xmlparsetest;

import android.util.Log;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Created by Linux on 2016/3/16.
 */
public class ContentHandler extends DefaultHandler {
    private final static String TAG = "MainActivity";
    private String nodeName;
    private StringBuilder name;
    private StringBuilder address;
    private StringBuilder say;private StringBuilder sex;

    // 文档开始时执行
    @Override
    public void startDocument() throws SAXException {
        name = new StringBuilder();
        address = new StringBuilder();
        say = new StringBuilder();
        sex = new StringBuilder();
        coment = new StringBuilder();
    }

    // 元素开始时执行
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // 记录当前结点名
        nodeName = localName;
        if (nodeName.equals("name") && attributes != null) {
            sex.append(attributes.getValue("sex"));
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // 根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
        if ("name".equals(nodeName)) {
            name.append(ch, start, length);
        } else if ("address".equals(nodeName)) {
            address.append(ch, start, length);
        } else if ("say".equals(nodeName)) {
            say.append(ch, start, length);
        }
    }

    // 元素结束时执行
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("person".equals(localName)) {
            Log.d(TAG, "name is " + name.toString().trim());
            Log.d(TAG, "adress is " + address.toString().trim());
            Log.d(TAG, "say is " + say.toString().trim());
            Log.d(TAG, "sex is " + sex.toString().trim());
            // 最后要将StringBuilder清空掉
            name.setLength(0);
            address.setLength(0);
            say.setLength(0);
            sex.setLength(0);
        }
    }

    // 文档结束时
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
}</span>
在MainActivity中定义方法,进行SAX解析

<span style="font-family:Courier New;">// sax解析数据
public void saxParse(View view) {
    String xmlData = getXMLData(fileName);
    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();
    }
}</span>

打印日志如下:

<span style="font-family:Courier New;">03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: name is 盖伦
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: adress is 德玛西亚
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: say is 我将带头冲锋
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: sex is man
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: name is 亚索
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: adress is 艾欧尼亚
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: say is 死亡如风,常伴吾身
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: sex is man
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: name is 瑞雯
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: adress is 诺克萨斯
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: say is 战争与谋杀之间,潜藏着我们的心魇
03-16 18:10:55.732 24745-24745/com.example.linux.xmlparsetest D/MainActivity: sex is girl</span>


Sax与Pull的比较:

区别:

  • SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束
  • PULL解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析

 

相似性:

  Pull解析器也提供了类似SAX的事件,开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等,但需要调用next() 方法提取它们(主动提取事件)。

 

使用:

  如果在一个XML文档中我们只需要前面一部分数据,但是使用SAX方式或DOM方式会对整个文档进行解析,尽管XML文档中后面的大部分数据我们其实都不需要解析,因此这样实际上就浪费了处理资源。使用PULL方式正合适。



Android 利用PULL生成XML文档

//目录结构 //StudentBean.java package sn.len.domain; public class StudentBean { private Strin...

android学习笔记(5)-SharedPreferences方式保存用户喜好参数(附pull解析Xml文档详解)

SharedPreferences保存用户喜好参数 很多时候我们需要对处理的数据进行存储,以供再次访问,这里介绍一种数据存储方式 SharedPreferences 他是一个较轻量级的存储类,...

Android学习笔记(八)XML文档的解析

一、废话   最近几天四川一直下雨,冷!今天到成都的时候,下午3点多的天和晚上天差不多,黑呼呼的... ...难道传说的2012来了?哈哈哈... ... 二、正文     在上一篇笔记中提到过...

android的sax解析XML文档

最近做了一些SAX解析的一些东西,整合了学校的自习室的情况,目的是为那些考研亦或是想学习的童鞋提供一些简单的帮助 一、.首先布局一下所要设计的界面 1  第一个界面的布局 ...

android DOM 解析 网络上xml文档

解析xml文档在很多时候都要用到,比如像音乐播放器的网络歌曲列表,应用软件的下载列表等等。想要更新时只需要更改服务器上的xml文档即可,然后客户端读取固定的xml来显示相应的列表,先给出xml文档 ...
  • dangxw_
  • dangxw_
  • 2013年11月09日 10:54
  • 961

Android XML文档解析(一)——SAX解析

在Android中,常见的XML解析器分别为SAX解析器、DOM解析器和PULL解析器. SAX,全称Simple API for XML,既是指一种接口,也是指一个软件包。SAX解析XML文件采用事...

Android SAX,DOM,PULL解析XML文档

一,写XML XiaoYang 19 XiaoZhang 28 XiaoZhao 38 二,编写对应XML的bean类 package sn...

android应用中使用xmlpull解析xml文档失败

本人刚入门android 在看黎活明老师的android视频做一资讯客户端案例,使用android应用从web应用程序中获取xml数据再进解析成资讯实体,基本上按照视频上的操作可是我的应用就是失败了...

Android网络下使用SAX解析XML文档

作者:王震                   SAX全称是:Simple API for XML。SAX是基于事件驱动的,android的事件机制是基于回调函数的,在用SAX解析xml文档时候,在...

学习笔记 --android将数据存放及xml文档常用的 方法

android用来存储数据到Xml文件的方式很多,今天写的是安卓常用的方式,此方式较其他方式简单一些,所以也是android常用的。 此方式基于面向对象的思想,利用的是XmlSerializer...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android XML文档简析
举报原因:
原因补充:

(最多只允许输入30个字)