一、什么是SAX
在Android平台解析XML主要使用SAX标准。
SAX全称Simple API for XML,既是指一种接口,也是指一个软件包。作为接口,SAX是事件驱动型/XML解析的一个标准接口。
二、SAX基本原理
SAX的工作原理简单的说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知时间处理函数,由时间处理函数做相应动作,然后继续同样的扫描,直至文档结束。 以事件为驱动。
1、SAX实现都会产生以下类型的事件:
- 在文档的开始和结束时触发文档处理事件
- 在文档内每一个XML元素接受解析的前后触发元素事件
- 任何元数据通常都由单独的事件交付
- 在处理文档的DTD或Schema是产生DTD或Schema事件
- 产生错误时间用来通知主机应用程序解析错误
2、SAX解析模型
1)、SAXParserFactory
其为SAXParser对象的工厂对象,使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档
获取该类实例的方法:SAXParserFactory.newInstance()
2)、SAXParser(解析器)
利用其包装的XMLReader(包装器)解析来自文件、输入流、URL中的XML,并把解析事件报告给提定的处理器
获取XMLReader方法:
XMLReader reader=SAXParserFactory.newInstance().newSAXParser().getXMLReader();
reader.parse(InputSource input);
3)、DefaultHandler
为了实现ContentHandler接口,不得不把ContentHandler中所有的抽象方法都实现,这样比较麻烦。 SAX API已经考虑到这个问题,在它的org.xml.sax.helper包中为我们提供了一个方便实现各种处理器接口的帮助类DefaultHandler。其实现了四个核心 SAX2 处理程器接口中的所有回调(适配器模式),该类需要开发者自行继承,并实现“感兴趣”的方法。
3、 SAX解析文档过程
<doc>
<para>Hello,XML!</para>
</doc>
当一个SAXParser遇到以上的XML时,依次会调用:startDocument, startElement, startElement, startElement, characters(如内容很长可 能会有若干次),endElement, endElement, endElement,endDocument。
4、在解析文档的过程中会产生如下一系列事件:
1)、创建事件处理程序。——MyContenetHandler
2)、创建SAX解析器。——SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();
3)、将事件处理程序分配给解析器。
reader.setContentHandler(new MyContentHandler());
4)、对文档进行解析,将每个事件发送给处理程序。
reader.parse(new InputSource(new StringReader(resultStr)));
三、SAX常用接口
ContentHandler接口是Java类包中的一个特殊 的SAX接口,位于org.xml.sax包中。该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档的时候,他会遇到某些特殊的事件,比如文档的开始和结束、元素的开始和结束、以及元素中的字符数据等事件。当遇到这些事件是,XML解析器会调用ContentHandler接口中相 应的方法来相应该事件。
ContentHandler接口的方法有以下几种:
void startDocument()
void endDocument()
void startElement(String uri,String localName,String qName,Attributes atts)
void endElement(String uri,String localName,String qName)
void characters(char[] ch,int start,ing length)
四、实现步骤:
1)、实现继承自DefalutHandler适配器的实现类,覆写“感兴趣”的方法
2)、获得SAXParserFactory实例
3)、由SAXParserFactory获得XMLReader实例
4)、注册处理文档内容解析事件的ContentHandler
5)、调用XMLReader实例的parser方法,此时需给出“XML源”
<?xml version="1.0" encoding="UTF-8"?>
<teachers>
<teacher id="1">
<name>bauble</name>
<sex>男</sex>
<subject>数学</subject>
</teacher>
<teacher id="2">
<name>allorry</name>
<sex>男</sex>
<subject>英语</subject>
</teacher>
<teacher id="3">
<name>lily</name>
<sex>女</sex>
<subject>语文</subject>
</teacher>
</teachers>
public class XMLActivity extends Activity {
private Button parseButton ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
parseButton = (Button)findViewById(R.id.parseButton);
parseButton.setOnClickListener(new ParseButtonListener());
}
class ParseButtonListener implements OnClickListener{
public void onClick(View v) {
HttpDownLoader hd = new HttpDownLoader();
String resultStr = hd.downLoad("http://127.0.0.1:8080/download/test.xml");
System.out.println(resultStr);
try{
//创建一个SAXParserFactory解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();
//为XMLReader设置内容处理器,逐行扫描文件,遇到标签等会触发相应的函数在MyContentHandler中
reader.setContentHandler(new MyContentHandler());
//开始解析文件
reader.parse(new InputSource(new StringReader(resultStr)));
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
public class MyContentHandler extends DefaultHandler {
String name,sex, subject;
String tagName;
public void startDocument() throws SAXException {
System.out.println("-----------begin-----------");
}
public void endDocument() throws SAXException {
System.out.println("-------------end-----------");
}
public void startElement(String namespaceURI, String localName,
String qName, Attributes attr) throws SAXException {
tagName = localName;
if (localName.equals("teacher")) {
//获取标签的全部属性
for (int i = 0; i < attr.getLength(); i++) {
System.out.println(attr.getLocalName(i) + "=" + attr.getValue(i));
}
}
}
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
//在teacher标签解析完之后,会打印出所有得到的数据
tagName = "";
if (localName.equals("teacher")) {
this.print();
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
if (tagName.equals("name")){
name = new String(ch, start, length);
}else if (tagName.equals("sex")){
sex = new String(ch, start, length);
}else if (tagName.equals("subject")){
subject = new String(ch, start, length);
}
}
private void print() {
System.out.print("name: ");
System.out.println(name);
System.out.print("sex: ");
System.out.println(sex);
System.out.print("subject: ");
System.out.println(subject);
System.out.println();
}
}