1.什么是SAX
答:Android平台解析XML主要是使用SAX这么一个标准。日常开发中有两种常见方式解析XML,一种是SAX;另一种就是DOM(文档对象模型),把XML文档看做一棵树,有根节点,子节点和叶节点,首先要把XML文档全部装载在内存中,然后解析成一棵树,在树上进行相应的操作,好处就是操作简单方便,缺点就是当处理文档比较大,性能上就会存在一些问题。
SAX是逐行的扫描文档,可一边扫描一边解析,可以在解析文档的任意时刻来停止这次解析。缺点是操作起来稍微复杂一些,通过SAX往XML文档中添加或删除内容比较费劲。
2.SAX基本原理
答:SAX(Simple API for XML),既是指一种接口,也是指一个软件包。
作为接口,SAX是事件驱动型XML解析的一个标准接口
SAX是一个标准,做出这个标准就是为了解析XML文档
SAX的工作原理简单的说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素(element)开始与结束,文档结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。(以事件为驱动的解析的过程)
大多数SAX实现都会产生以下类型的事件:
在文档的开始和结束时触发文档处理事件。
在文档内每一个XML元素接受解析的前后触发元素事件。
任何元数据通常都由单独的事件交付。
在处理文档的DTD或Schema时产生DTD或Schema事件。
产生错误事件用来通知主机应用程序解析错误。
SAX模型
解析文档过程
对于如下文档:
<doc>
<para>Hello,world! </para>
</doc>
在解析文档的过程中会产生如下一系列事件
start document (1)创建事件处理程序
start element:doc (2)创建SAX解析器
start element:para (3)将事件处理程序分配给解析器
characters: Hello,world! (4)对文档进行解析,将每个事件发送给处理程序
end element:para
end element:doc
end document
SAX常用接口
答: ContentHandler接口
ContentHandler是java类包中一个特殊的SAX接口,位于org.xml.sax包中。该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件,比如文档的开头和结束,元素的开头和结束,以及元素中的字符数据等事件。当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件。
ContentHandler接口的方法有以下几种:
void startDocument(); void endDocument();
void startElement(String uri,String localName,String qName,Attributes arrs);
void endElement(String uri,String localName,String qName);
void character(char[] ch,int start,int length);//得到标签之间的内容
其中,uri表示得到当前正在解析的标签的命名空间;localName是不带前缀的标签值,qName是带前缀的标签值;Attributes表示得到标签所有属性。
注意:要非常小心这里的character方法。
在图中标明2的地方会调用characters(char[] ch, int start, int length)方法,不要以为那里是空白,Sax解析器可不那么认为,Sax解析器会把它认为是一个TextNode。但是这个空白不是我们想要的数据,我们是想要<name>节点下的文本信息。这就要定义一个记录当上一节点的名称的TAG,在characters(.....)方法中,判断当前节点是不是name
XMLActivity.java
- package com.examples.xml;
- import java.io.IOException;
- import java.io.StringReader;
- import javax.xml.parsers.ParserConfigurationException;
- import javax.xml.parsers.SAXParserFactory;
- import org.xml.sax.InputSource;
- import org.xml.sax.SAXException;
- import org.xml.sax.XMLReader;
- import com.examples.utils.HttpDownloader;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class XMLActivity extends Activity {
- /** Called when the activity is first created. */
- private Button parseBtn;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- parseBtn =(Button)findViewById(R.id.parseBtn);
- parseBtn.setOnClickListener(new parseBtnListener());
- }
- class parseBtnListener implements OnClickListener
- {
- @Override
- public void onClick(View v) {
- HttpDownloader httpdown = new HttpDownloader();
- String result = httpdown.download("http://202.193.82.14:8080/vao1500/test.xml");
- System.out.println(result);
- //创建一个SAXParserFactory
- SAXParserFactory saxParser = SAXParserFactory.newInstance();
- try {
- XMLReader xmlReader=saxParser.newSAXParser().getXMLReader();
- //为xmlReader设置内容处理器
- xmlReader.setContentHandler(new MyContentHandler());
- //开始解析文件
- xmlReader.parse(new InputSource(new StringReader(result)));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
MyContentHandler.java
- package com.examples.xml;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- public class MyContentHandler extends DefaultHandler
- {
- String sName,sSex,sAddress,sStatus,sMoney;
- String tagName;
- @Override
- public void startDocument() throws SAXException {
- System.out.println("start------------->");
- }
- @Override
- public void endDocument() throws SAXException {
- System.out.println("end------------->");
- }
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- tagName = localName;
- if(localName.equals("worker"))
- {
- //获得标签全部属性
- for(int i=0;i<attributes.getLength();i++)
- {
- System.out.println(attributes.getLocalName(i) + " = "+ attributes.getValue(i));
- }
- }
- }
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- //在worker标签解析之后,会打印出所有得到的数据
- if(localName.equals("worker"))
- {
- this.printout();
- }
- tagName = null;
- }
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if(tagName !=null)
- {
- if(tagName.trim().equalsIgnoreCase("name"))
- {
- sName = new String(ch,start, length);
- }else if(tagName.trim().equalsIgnoreCase("sex"))
- {
- sSex = new String(ch,start, length);
- }else if(tagName.trim().equalsIgnoreCase("address"))
- {
- sAddress = new String(ch,start, length);
- }else if(tagName.trim().equalsIgnoreCase("status"))
- {
- sStatus = new String(ch,start, length);
- }
- else if(tagName.trim().equalsIgnoreCase("money"))
- {
- sMoney = new String(ch,start, length);
- }
- }
- }
- public void printout()
- {
- System.out.print("name:");
- System.out.println(sName);
- System.out.print("sex:");
- System.out.println(sSex);
- System.out.print("address:");
- System.out.println(sAddress);
- System.out.print("status:");
- System.out.println(sStatus);
- System.out.print("money:");
- System.out.println(sMoney);
- }
- }
-
- 原作者:http://blog.csdn.net/xutaogenlanqiu/article/details/6612925