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

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

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

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. GF(2^8)乘法

    最近在学AES,实现了一下伽罗瓦域(2^8)乘法. 至于什么是伽罗瓦域解释起来比较复杂,我也不一定能解释清楚,自行google.这里只是给出一个简单直观的实现. #include<iostrea ...

  2. android开发常用组件(库)推荐

    版本兼容:官方 support 全家桶 网络请求:Android-Async-Http.Retrofit.OkHttp.Volley图片加载:Glide 和 Universal-Image-Loade ...

  3. javascript 缓冲运动demo

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. SUBTOTAL 函数与所在行

    SUBTOTAL 函数与所在行 设计要点:数据汇总.隐藏.筛选 阿金:给你推荐一个函数SUBTOTAL. 秀秀:又是函数!俺不喜欢. 阿金:虽然你不喜欢函数,但是你也离不了啊,比如汇总. 秀秀:那倒是 ...

  5. HDU 1874-畅通project续(最短路Dijkstra+优先队列)

    畅通project续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. (3)选择元素——(15)总结(Summary)

    With the techniques that we have covered in this chapter, we should now be able to locate sets of el ...

  7. 採集和输出 DeckLink Studio 4K

  8. js控制select数据绑定下拉列表

    JS代码段:  <script type="text/javascript"> $(document).ready(function () { $("sele ...

  9. USB 管道 && 端点

    管道是对主机和usb设备间通信流的抽象.      管道和usb设备中的端点一一对应,一个usb设备含有多少个端点,其和主机进行通信时就可以使用多少条管道,且端点的类型决定了管道中数据的传输类型.  ...

  10. IE浏览器下a标签嵌套img标签默认带有边框

    最近写在线主页时发现IE浏览器下a标签嵌套img标签默认带有边框: 解决办法:img{border:0 none;} 注意,严格意义上0和none都要加上!