------------------------------------------------------------------------------------------------------

此文章仅作为学习交流所用

转载或引用请务必注明原文地址:

http://blog.csdn.net/luzhenrong45/article/details/11851607

或联系作者:luzhenrong45@gmail.com

谢谢!

 ------------------------------------------------------------------------------------------------------

一. XML介绍

XML:extensible markup language,可扩展标记语言. 与HTML(超文本标记语言,即Hypertext Markup Language)一样,XML也是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML与HTML的设计区别是:XML 被设计为传输和存储数据,其焦点是数据的内容。而HTML 被设计用来显示数据,其焦点是数据的外观。HTML 旨在显示信息,而 XML 旨在传输信息。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。其目的是为了促进Internet上结构化文档的交换。简单的说,XML是一组规则和准则的集合,用于以无格式文本来描述结构化数据.

XML是纯数据描述,与编程语言、操作系统或传输协议无关,从而将数据从以代码为中心的基础结构所产生的约束中解放出来,让数据能够在Web上更自由的流通。然而XML本身只是以纯文本对数据进行编码的一种格式,要想利用XML,或者说利用XML文件中所编码的数据,必须先将数据从纯文本中解析出来,因此,必须有一个能够识别XML文档中信息的解析器,用来解释XML文档并提取其中的数据。根据数据提取的不同需求,又存在着多种解析方式,不同的解析方式有着各自的优缺点和适用环境。选择合适的XML解析技术能够有效提升应用系统的整体性能.在Android中,常见的XML解析器分别为SAX解析器、DOM解析器和PULL解析器.

下面,介绍SAX解析方式.

二.  SAX解析

SAX,全称Simple API for XML,既是指一种接口,也是指一个软件包。SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时回调你写好的事件处理程序,然后继续同样的扫描,直至文档结束。使用SAX的优势在于其解析速度较快,占用内存较少(相对于DOM而言)。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说,在处理某个标签的时候,比如在 startElement方法中,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。

//用于处理文档解析开始事件

public void startDocument()throws SAXException

//处理元素开始事件,从参数中可以获得元素所在名称空间的uri,元素名称,属性类表等信息

public void startElement(String namespacesURI , String localName , String qName , Attributes atts) throws SAXException

//处理元素结束事件,从参数中可以获得元素所在名称空间的uri,元素名称等信息

public void endElement(String namespacesURI , String localName , String qName) throws SAXException
//处理元素的字符内容,从参数中可以获得内容 public void characters(char[] ch , int start , int length) throws SAXException //当文档结束的时候,调用这个方法,可以在其中做一些善后的工作
public void endDocument() throws SAXException

三. SAX解析XML步骤

Android 使用SAX解析XML文件有两种方式,第一是直接使用SAXParser,或者创建一个XMLReader.不管采用哪种方式,前面三个步骤是一样的.

(一)第一步:加载需要解析的文件,将一个xml文档或者资源变成一个java可以处理的InputStream流.比如我的xml文件名是laolu_xml.xml,放在src目录下,可通过类装载器的方式获得文件路径,再获得文件的输入流

InputStream is= this.getClass().getClassLoader().getResourceAsStream("laolu_xml.xml");

(二)第二步:新建一个工厂类SAXParserFactory

SAXParserFactory factory = SAXParserFactory.newInstance();

(三)第三步:让工厂类产生一个SAX的解析类SAXParser

SAXParser saxParser = factory.newSAXParser();

(四)第四步:可以采用XMLReader解析或直接使用SAXParser解析.

(1)采用XMLReader

1) 从SAXPsrser中得到一个XMLReader实例

XMLReader xmlReader = saxParser.getXMLReader();

2) 把自己写的handler注册到XMLReader中,一般最重要的就是ContentHandler:

SAXForHandler handler = new SAXForHandler ();  //SAXForHandler为自己写的SAX解析类
xmlReader.setContentHandler(handler);
3) 开始解析XML
xmlReader.parse(new InputSource(is));

(2)直接使用SAXParser解析

SAXForHandler handler = new SAXForHandler ();
saxParser.parse(is,handler);

两种方式都可以对XML文件进行解析,使用的效果是完全一样的.其实SAXParser是JAXP(JAVA API for XML Processing) 对XMLReader的一个封装,只不过,SAXParser能接受更多类型的参数,能方便对不同数据源的XML文档进行解析,使用XMLReader要稍微烦琐一些.

四.SAX解析实例.

(一)下面以一个工程实例来实现SAX对XML文件的解析.新建一个xml文件: laolu_xml.xml,该文件放在工程根目录下面.内容如下:

<?xml version="1.0"  encoding="UTF-8"?>
<persons>
<person id="0">
<name>刘德华</name>
<sex>男</sex>
<age>21</age>
</person>
<person id="1">
<name>张漫玉</name>
<sex>女</sex>
<age>22</age>
</person>
<person id="2">
<name>张易谋</name>
<sex>男</sex>
<age>23</age>
</person>
<person id="3">
<name>周新驰</name>
<sex>未知</sex>
<age>24</age>
</person>
<person id="4">
<name>纳兰容若</name>
<sex>男</sex>
<age>25</age>
</person>
</persons>

(二)先看一下实际效果图,Android对于XML解析,主要有sax,dom,pull三种方式,这里只介绍sax方式.其他两种以后再介绍.

(三)工程源码框架

(1)布局文件:

main_xml.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".XML_ParseActivity" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/sax_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/sax_parse"/>
<Button
android:id="@+id/dom_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dom_parse"
/>
<Button
android:id="@+id/pull_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pull_parse"
/>
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView> </LinearLayout>

listview_xml.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" > <View
android:layout_width="0.5px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible" /> <TextView
android:id="@+id/id"
android:layout_width="60dip"
android:layout_height="40dip"
/>
<View
android:layout_width="0.5px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible" /> <TextView
android:id="@+id/name"
android:layout_width="120dip"
android:layout_height="40dip"
/> <View
android:layout_width="0.5px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible" /> <TextView
android:id="@+id/sex"
android:layout_width="60dip"
android:layout_height="40dip"
/> <View
android:layout_width="0.5px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible" /> <TextView
android:id="@+id/age"
android:layout_width="120dip"
android:layout_height="40dip"
/> </LinearLayout>

(2)这里重写了SimpleAdapter适配器,使用ListView的效果更好看一点.当然,这一点跟今天的主题没关.

MySimpleAdapter.java

package com.laolu.adapter;

import java.util.List;
import java.util.Map; import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SimpleAdapter; public class MySimpleAdapter extends SimpleAdapter
{ public MySimpleAdapter(Context context,
List<? extends Map<String, ?>> data, int resource, String[] from,
int[] to)
{
super(context, data, resource, from, to);
} @Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view=null;
if(convertView!=null)
{
view=convertView;
}else
{
view=super.getView(position,convertView,parent); }
int colors[]={Color.GRAY,Color.WHITE};
view.setBackgroundColor(colors[position%2]); // 每个item之间颜色不同 return super.getView(position, view, parent);//返回自己的view } }

(3)自己实现的SAX解析类SAXForHandler,继承DefaultHandler,而DefaultHandler是实现了ContenHandler的接口的.ContentHandler提供了之前所说的相应的事件方法,所以这个类是最重要的.因为这些回调函数都是自己写代码实现的.

SAXForHandler.java

package com.laolu.parser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import android.util.Log; public class SAXForHandler extends DefaultHandler
{
private static final String TAG="SAXForHandler";
private List<Map<String,Object>> persons;
private Map<String,Object> person; private String nowWitch;
public List<Map<String,Object>> getPersons()
{
return persons;
} @Override
public void startDocument() throws SAXException {
persons=new ArrayList<Map<String,Object>>();
Log.i(TAG,"***startDocument()***");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
if("person".equals(localName))
{
for(int i=0;i<attributes.getLength();i++)
{
Log.i(TAG,"arrtributes: "+attributes.getLocalName(i)+"_attributes_Value"
+attributes.getValue(i));
person=new HashMap<String,Object>();
person.put("id", attributes.getValue(i)); }
}
nowWitch=localName;
Log.i(TAG, qName+"***startElement()***"); }
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String data=new String(ch,start,length).trim();
if(!"".equals(data.trim()))
{
Log.i(TAG, "content: "+data.trim());
}
if("name".equals(nowWitch))
{
person.put("name", data.trim());
}else if("age".equals(nowWitch))
{
person.put("age", data.trim());
}else if("sex".equals(nowWitch))
{
person.put("sex", data.trim());
} } @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
Log.i(TAG,qName+"***endElement()***");
if("person".equals(localName))
{
persons.add(person);
person=null;
}
nowWitch=null;
}
@Override
public void endDocument() throws SAXException {
Log.i(TAG, "***endDocument()***");
} }

(4)主Activity,按下按键,ListView显示解析结果.

package com.laolu.main;

import java.io.InputStream;
import java.util.List;
import java.util.Map; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import com.example.xml.R;
import com.laolu.adapter.MySimpleAdapter;
import com.laolu.parser.SAXForHandler; import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView; public class XML_ParseActivity extends Activity
{
private static final String SAX="SAX_Parse";
private static final String DOM="DOM_Parse";
private static final String PULL="Pull_Parse";
ListView listView; @Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_xml);
listView=(ListView) findViewById(R.id.listview); Button saxButton=(Button) findViewById(R.id.sax_btn);
Button domButton=(Button) findViewById(R.id.dom_btn);
Button pullButton=(Button) findViewById(R.id.pull_btn);
saxButton.setOnClickListener(new MyListener());
domButton.setOnClickListener(new MyListener());
pullButton.setOnClickListener(new MyListener());
} public class MyListener implements OnClickListener
{ @Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.sax_btn:
try{
updateListViewBySAX();
}catch(Exception e)
{
Log.i(SAX,"SAX Exception!!!");
}
break;
case R.id.dom_btn:
break;
case R.id.pull_btn:
break; } } }
public void updateListViewBySAX() throws Exception
{
InputStream inputStream = this.getClass().getClassLoader().
getResourceAsStream("laolu_xml.xml");
SAXForHandler saxForHandler = new SAXForHandler();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(inputStream, saxForHandler);//采用 List<Map<String,Object>> persons = saxForHandler.getPersons();
SimpleAdapter simpleAdapter=new MySimpleAdapter(this, persons, R.layout.listview_xml,
new String[]{"id","name","sex","age"}, new int[]{R.id.id,R.id.name,R.id.sex,R.id.age});
listView.setAdapter(simpleAdapter);
inputStream.close(); } }

Android XML文档解析(一)——SAX解析的更多相关文章

  1. JavaEE实战——XML文档DOM、SAX、STAX解析方式详解

    原 JavaEE实战--XML文档DOM.SAX.STAX解析方式详解 2016年06月22日 23:10:35 李春春_ 阅读数:3445 标签: DOMSAXSTAXJAXPXML Pull 更多 ...

  2. Java解析XML文档(简单实例)——dom解析xml

      一.前言 用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object ...

  3. XML文档的生成和解析操作方法

    XML文档和JSon文档同为网络传输中的数据格式,JSon的解析和创建已经在新浪微博的使用中相当熟悉,故仅仅记载XML文档的相关方法. 关于XML文档: 1.一种便于编辑和传输的数据文件格式 2.xm ...

  4. [Swift通天遁地]七、数据与安全-(1)XML文档的创建和解析

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  5. 程序员带你学习安卓开发-XML文档的创建与解析

    这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:程序员带你学习安卓开发系列-Android文件存储 因知识连贯性推荐关注头条号:做全栈攻城狮.从头开 ...

  6. Java高级特性 第14节 解析XML文档(2) - SAX 技术

    一.SAX解析XML文档 SAX的全称是Simple APIs for XML,也即XML简单应用程序接口.与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式.当使用S ...

  7. 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)

    众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...

  8. 四种生成和解析XML文档的方法详解

    众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...

  9. 大杂烩 -- 四种生成和解析XML文档的方法详解

    基础大杂烩 -- 目录 众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J DOM:在现在的Java JDK里都自带了,在xml-apis.jar包 ...

随机推荐

  1. 多线程面试题(Google)

    有四个线程1.2.3.4.线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD.初始都为空.现要让四个文件呈如下格式: A:1 2 3 4 1 2.... ...

  2. Day02_VI基本操作及C基础

    2013年09月30日 星期一 09时37分03秒 回顾:     1. linux系统的知识背景     2. vi的使用 在正常模式下使用nyy可以把光标所在行开始的连续n行拷贝到剪贴板上去 在正 ...

  3. sublime3 使用技巧

    Ctrl+O(Command+O)可以实现头文件和源文件之间的快速切换 Ctrl+Shift+T可以打开之前关闭的tab页,这点同chrome是一样的 Ctrl+R定位函数:Ctrl+G定位到行: 插 ...

  4. (原)Mac下Apache添加限制IP线程模块:mod_limitipconn.so

    1.下载:http://dominia.org/djao/limit/mod_limitipconn-0.24.tar.bz2 解压到一个目录:我的是~/Download/mod_limitipcon ...

  5. android工程gen目录中R.java包名是怎么确定

    新建一个工程,包名用的com.mythroad.adskiller, 后来觉得不好,又改成com.mythroad.adsinscepter,但是我发现gen下的R.java文件的包名还是原来的com ...

  6. springmvc的运行流程分析

    前几篇文章对springmvc讲解的很清楚,大家看下,有问题,我们再一起讨论. 其实springmvc最为重要是它的运行流程,接着,我们来分析一下,其运行过程,废话不多说,看图说话: 分析如下: 1, ...

  7. 【VS2015正式版下载】Visual Studio 2015 正式版开放下载 Visual Studio 2015 神key

    说明: 微软定于2015年7月20日发布Visual Studio 2015正式版,目前其官方网站已经提供正式版本的下载. 可在https://www.visualstudio.com/en-us/d ...

  8. Neral的前言

    大家好,我是Neral,我准备写一个js库. 在动笔之前,我一直都处在很忐忑的状态,因为我写代码讲究的是一种感觉,那是看到自己写的代码之后大脑中就出现之后的无数个编码分支的快感,但是,如果很长一段时间 ...

  9. Spring框架快速入门之简介

    Spring是java平台上的一个开源应用框架.它的第一个版本是由Rod Johnson写出来的.Rod在他的Expert One-On- One Java EE Design and Develop ...

  10. permission is only granted to system apps--Android manifest权限问题

    在android的manifest.xml下编辑如下代码:<uses-permission android:name="android.permission.INTERNET" ...