:Android网络编程--XML之解析方式:SAX

任何放置在资源(res)目录下的内容可以通过应用程序的R类访问,这是被Android编译过的,而任何放置在资产(assets)目录下的内容会保持它的原始文件格式,为了读取它们,必须使用AssetManager来以字节流的方式读取文件,所以文件和数据保存在资源中更方便访问。

2. 凡是在R文件中定义的资源都可以通过 “@Static_inner_classes_name/resourse_name”的方式获取如:“@id/button”, @string/app_name。表达式:“@+id/button”,意思是在不久文件中为一些组件添加id属性。+表表示在R.java的名为id的内部类中添加一条记录。

 

XML:是Internet环境中跨平台的依赖于内容的技术,是当前处理结构化文档信息的有力工具。使用一系列简单的标记描述数据。(76)

SAX: 是一种以事件为驱动的XML API,由它定义的事件流可以指定从解析器传到专门的处理程序代码的XML结构,简单的讲,它是个解析速度快,占用内存少的解析器,这种技术特别适用于Android等移动设备。

 

备注:以事件为驱动

简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数).当然事件不仅限于用户的操作. 事件驱动的核心自然是事件。从事件角度说,事件驱动程序的基本结构是由一个事件收集器、一个事件发送器和一个事件处理器组成。事件收集器专门负责收集所有事件,包括来自用户的(如鼠标、键盘事件等)、来自硬件的(如时钟事件等)和来自软件的(如操作系统、应用程序本身等)。事件发送器负责将收集器收集到的事件分发到目标对象中。事件处理器做具体的事件响应工作,它往往要到实现阶段才完全确定,因而需要运用虚函数机制(函数名往往取为类似于HandleMsg的一个名字)。对于框架的使用者来说,他们唯一能够看到的是事件处理器。这也是他们所关心的内容。

 

DEMO:使用SAX解析XML文档:

1.创建一个Person类,存放相关的信息:

package com.example.model;

public class Person {
private Integer id;
private String name;
private Short age;

public Person() {
// TODO Auto-generated constructor stub
}


public Person(Integer id, String name, Short age) {
super();
this.id = id;
this.name = name;
this.age = age;
}


public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Short getAge() {
return age;
}

public void setAge(Short age) {
this.age = age;
}

@Override
public String toString() {
// TODO Auto-generated method stub
return "id=" +id +",name="+name+",age=" + age;
}

}

2.创建一个SAXForHandler类,继承自DefaultHandler,DefaultHandler实现了ContentHandler,ContentHandler提供了相应的方法。

package com.example;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import com.example.model.Person;

public class SAXForHandler extends DefaultHandler {
private static final String TAG = "SAXForHandler";
private List<Person> persons;
private String perTag; // record the name of previous tag
Person person;// current person

public List<Person> getPersons() {
return persons;
}

/**
* 在开始解析文档时执行一次
*/
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
persons = new ArrayList<Person>();
Log.i(TAG, "****startDocument()****");
}

@Override
public void endDocument() throws SAXException {
Log.i(TAG, "****endDocument()****");
}

/**
* uri:命名空间
* localName:标签名称
* qName:带 命名空间的标签名
* attributes:存放该标签的所有属性
*/
@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, "attributeName:" + attributes.getLocalName(i) + ",attribute_value" +attributes.getValue(i) );
person = new Person();
person.setId(Integer.valueOf(attributes.getValue(i)));
}
}
perTag = localName;
Log.i(TAG, qName + "****startElement()****" );

}

@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;
}
perTag = null;
}

/**
* ch:当前读取到的TextNode节点
* start:字节开始的位置,如果要读取全部,那就是从0开始
* length:当前TextNode的长度
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String data = new String(ch,start,length).trim();
if(!"".equals(data)){
Log.i(TAG, "content" + data);
}
if("name".equals(perTag)){
person.setName(data);
}else if("age".equals(perTag)){
person.setAge(new Short(data));
}
}

}

 

3.创建一个person.xml文件放在src下:

<?xml version="1.0" encoding="utf-8"?>
<persons>
<person id="1">
<name>wyy</name>
<age>27</age>
</person>
<person id="2">
<name>cL</name>
<age>26</age>
</person>
</persons>

4.测试的activity:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
List<Person> ps = sax_XML();
for (int i = 0; i <ps.size(); i++) {
Person p = ps.get(i);
Log.i("AA", p.getName() +"id="+p.getId()+",age="+p.getId() );
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

public List<Person> sax_XML() throws Exception{
//通过类加载器获取路径,再以输入流的方式放入解析器。
InputStream is = MainActivity.class.getClassLoader().getResourceAsStream("wangyuanyuan.xml");

SAXForHandler handler = new SAXForHandler();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
//使用SAXParser
// saxParser.parse(is, handler);
//使用xmlReader
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(handler);
xmlReader.parse(new InputSource(is));
List<Person> list = handler.getPersons();
is.close();
return list;
}

}

 

两种方法使用SAXParser 和xmlReader都可以解析成功。

 

除了使用SAX我们还可以使用DOM、PULL等解析XML文档。其中PULL解析器被集成在了android系统中 。PULL解析器不仅仅可以解析XML还可以修改或者生成新的XML文件

 

 


不过最近在我们的项目中一般都是用json解析,更加简洁方便。

 

 

参考:百度百科、《Android 4.0 网络编程》

 

posted @ 2015-04-23 15:43  wangyy  阅读(191)  评论(0编辑  收藏  举报