您的位置:首页 > 编程语言 > Java开发

java xml解析 学习笔记(2)——SAX

2014-03-26 20:25 671 查看


     SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。

    选择DOM还是选择SAX? 对于需要自己编写代码来处理XML文档的开发人员来说, 选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。

    DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。

    SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据.

下面给出两个例子来简单的介绍下sax方式解析xml文件的方法:

xml文件:first.xml,放于src目录下

<?xml version="1.0" encoding="UTF-8"?>
<xml-body>
<result>
<value>
<no>
鲁B1234
</no>
<addr>
山东省青岛市
</addr>
</value>
<value>
<no>
鲁A1234
</no>
<addr>
山东省济南市
</addr>
</value>
</result>
</xml-body>

例一:(使用boolean标记解析)

package Test;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

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

public class MyXmlReader_sax extends DefaultHandler {
boolean isOkTag;
public static void main(String args[]) {
long lasting = System.currentTimeMillis();
try {
SAXParserFactory sf = SAXParserFactory.newInstance();    //1、创建SAXParserFactory 工厂
SAXParser sp = sf.newSAXParser(); 						 //2、创建SAXParser
MyXmlReader_sax reader = new MyXmlReader_sax();
sp.parse(new InputSource("src/first.xml"), reader); 	 //3、解析XML文档,并回调处理器的相应事件
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + "毫秒");
}

/*
* 接收元素开始的通知。
* 参数意义如下:
*    uri :元素的命名空间
*    localName :元素的本地名称(不带前缀)
*    qName :元素的限定名(带前缀)
*    atts :元素的属性集合
*/
public void startElement(String uri,String localName,String qName,Attributes attrs) {  //5、开始标记
//tags.push(qName);
if(qName.equals("value")) {
System.out.println("=============value start============");
}
if(qName.equals("no")) {
isOkTag = true;
System.out.print("车牌号:");
}else if(qName.equals("addr")){
isOkTag = true;
System.out.println("地址:");
}

}
/*
* 接收字符数据的通知。
*/
public void characters(char ch[], int start, int length) throws SAXException { 		//
if(isOkTag) {
System.out.println(new String(ch, start, length));
}
}

/*
* 接收文档的结尾的通知。
* 参数意义如下:
*    uri :元素的命名空间
*    localName :元素的本地名称(不带前缀)
*    qName :元素的限定名(带前缀)
*
*/
public void endElement(String uri, String localName, String qName)
throws SAXException {
isOkTag = false;
if(qName.equals("value")) {
System.out.println("=============value end============");
}
}

}

运行结果:



例二:(使用栈解析)

package Test;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

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

public class MyXmlReader_sax2 extends DefaultHandler {
//获取栈实例
java.util.Stack tags = new java.util.Stack();

public MyXmlReader_sax2() {
super();
}
//解析xml文件
public void getXML() {
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
MyXmlReader_sax2 parX = new MyXmlReader_sax2();
parser.parse("src/first.xml", parX);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 重写方法characters(...);
public void characters(char ch[], int start, int length)
throws SAXException {
//获取栈顶元素
String tag = (String) tags.peek();
// 比较栈顶元素
String text = new String(ch, start, length);
if(tag.equals("value")){
System.out.println("<value>");
tags.pop();   //出栈
}
if (tag.equals("no")) {
System.out.println(" <no>" + text);
tags.pop();
} else if (tag.equals("addr")) {
System.out.println(" <addr>" + text);
tags.pop();
}

}
// 重写方法startElement(...);
public void startElement(String uri, String localName, String qName,
Attributes attrs) {
tags.push(qName);// 把项压入栈顶(入栈)
// System.out.println(qName);
}
//重写方法endElement(...);
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
if(qName.equals("value")){
System.out.println("</value>");
}else if(qName.equals("no")){
System.out.println("</no>");
}else if(qName.equals("addr")){
System.out.println("</addr>");
}
}
public static void main(String[] args) {
new MyXmlReader_sax2().getXML();
}
}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: