使用SAX解析XML

前端之家收集整理的这篇文章主要介绍了使用SAX解析XML前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://blog.sina.com.cn/s/blog_5b8c66750100a9k3.html

一、前言

1. Xml技术简介
Xml文件有两种约束类型,包括文档类型定义(DTD)和Xml模式(Schema)。Xml DTD被包含在xml1的标准里。Xml 模式被包含在W3C的标准中。在xml 数据和xml模式两者之间有很多的区别。
A. xml模式支持的数据类型比xml DTD多;
B. xml模式在无序的情况下使用起来比xml DTD更方便;
C. xml模式支持名字空间,可以在不同的文件中定义相同的方法等。
D. xml模式形成的文档可以被多种标准解析,如dom,sax或者jdom等,而xml DTD方式下确不行。
2. Xml文件解析
在java语言环境里可以使用三种方法解析xml文件:dom(document object model),sax(simple apifor xml)和jdom(java document object model)。
SAX提供了基于事件的方式进行解析,适合于快速,数据量小的解析情况。SAX解析有几个缺陷:A.它的解析是连续的;B.数据无法回朔。
DOM解析不同于SAX。它提供了内存中完整的xml数据映像,数据被存储在树状结构中。DOM解析方式更容易获得和处理数据。
JDOM是java语言中特有的,主要用来支持xpath标准。

Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单APISimpleAPI for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOMSun公司提供了JavaAPI for XML ParsingJAXP)接口来使用SAXDOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。

JAXP接口包含了三个包:

(1)org.w3c.domW3C推荐的用于XML标准规划文档对象模型的接口。

(2)org.xml.sax用于对XML进行语法分析的事件驱动的XML简单APISAX

(3)javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。

二、前提

DOM编程不要其它的依赖包,因为JDK自带JDK里含有的上面提到的org.w3c.domorg.xml.saxjavax.xml.parsers包就可以满意条件了。

三、使用SAX解析XML文档

SAX是基于事件的简单API,同样的我们也是用一个最简单的例子来看看SAX是如何解析XML

先来看看我们要解析的XML代码

<?xml version="1.0"encoding="gb2312"?>

<books>

<bookemail="zhoujunhui">

<nameaddr="address">rjzjh</name>

<price>jjjjjj</price>

</book>

</books>

简单的不能再简单了。但是该有的都有了,根元素、属性、子节点。好了,能反应问题就行了,下面来看看解析这个XML文件Java代码吧!

1 public class SaxParse{

2public SaxParse(){

3SAXParserFactory saxfac=SAXParserFactory.newInstance();

4try {

5SAXParser saxparser=saxfac.newSAXParser();

6InputStream is=new FileInputStream("bin/library.xml");

7saxparser.parse(is,new MySAXHandler());

8} catch (ParserConfigurationException e) {

9e.printStackTrace();

10} catch (SAXException e) {

11e.printStackTrace();

12} catch (FileNotFoundException e) {

13e.printStackTrace();

14} catch (IOException e) {

15e.printStackTrace();

16}

17}

18 publicstatic void main(String[] args) {

19new SaxParse();

20}

21}

这段代码比较短,因为SAX是事件驱动的,它的大部分实现在在另一个Java文件中,先别管另一个文件,我们来一个个地分析吧!

1)得到SAX解析器的工厂实例

3SAXParserFactory saxfac=SAXParserFactory.newInstance();

这是一个javax.xml.parsers.SAXParserFactory类的实例

2)从SAX工厂实例中获得SAX解析器

5SAXParser saxparser=saxfac.newSAXParser();

使用javax.xml.parsers.SAXParserFactory工厂的newSAXParser()方法

3)把要解析的XML文档转化为输入流,以便DOM解析器解析它

6InputStream is=new FileInputStream("bin/library.xml");

InputStream是一个接口。

4)解析XML文档

7saxparser.parse(is,new MySAXHandler());

后面就不用看了,都是些没用的代码(相对而言),够简单的吧!

注意了,我们新建了一个实例newMySAXHandler()这个实例里面又有什么东西呢?

这个实例就是SAX的精华所在。我们使用SAX解析器时,必须实现内容处理器ContentHandler接口中的一些回调方法,然而我们不须要全部地实现这些方法,还好,我们有org.xml.sax.helpers.DefaultHandler类,看它的类申明:

public classDefaultHandler

implements EntityResolver,DTDHandler,ContentHandler,ErrorHandler

实现了这么多接口啊,其它的先不管了,至少它实现了ContentHandler这一接口。

好了,看看这个类有些什么吧?下面是它的Java代码

public class MySAXHandlerextends DefaultHandler {

boolean hasAttribute=false;

Attributes attributes=null;

public void startDocument() throws SAXException {

System.out.println("文档开始打印了");

}

public void endDocument() throws SAXException {

System.out.println("文档打印结束了");

}

public void startElement(String uri,String localName,StringqName,

Attributes attributes) throws SAXException {

if(qName.equals("books")){

return;

}

if(qName.equals("book")){

System.out.println(attributes.getQName(0)+attributes.getValue(0));

}

if(attributes.getLength()>0){

this.attributes=attributes;

this.hasAttribute=true;

}

}

public void endElement(String uri,StringqName)

throws SAXException {

if(hasAttribute&&(attributes!=null)){

for(inti=0;i<attributes.getLength();i++){

System.out.println(attributes.getQName(0)+attributes.getValue(0));

}

}

}

public void characters(char[] ch,int start,intlength)

throws SAXException {

System.out.println(new String(ch,start,length));

}

}

不要看它一大堆,我一一分解给大家看。我们说SAX是基于事件的API,我们这个类实到了ContentHandler接口中的如下方法

1startDocument()用于处理文档解析开始事件

public void startDocument() throws SAXException {

System.out.println("文档开始打印了");

}

2endDocument()用于处理文档解析结束事件

public void endDocument() throws SAXException {

System.out.println("文档打印结束了");

}

3startElement用于处理元素开始事件

public void startElement(String uri,

Attributes attributes) throws SAXException {

if(qName.equals("books")){

return;

}

if(qName.equals("book")){

System.out.println(attributes.getQName(0)+attributes.getValue(0));

}

if(attributes.getLength()>0){

this.attributes=attributes;

this.hasAttribute=true;

}

}

第二个参数StringqName表示这个元素的名字,如:

根节点<books></books>它的qName为“books

最底层节点<price>jjjjjj</price>它的qName为“price

知道这一点上面程序就好解释了,当遇到根元素“books”时就什么也不做跳过,当遇到“book”元素时就打出它的属性(它只有一个属性<bookemail="zhoujunhui"></book>)。

当是其它节点时(这下只剩下最底层的两个节点“name”和“price”了),就把它的属性取出来存到this.attributes域中,以后中元素结束事件好处理。

4endElement用于处理元素结束事件

public void endElement(String uri,StringqName)

throws SAXException {

if(hasAttribute&&(attributes!=null)){

for(inti=0;i<attributes.getLength();i++){

System.out.println(attributes.getQName(0)+attributes.getValue(0));

}

}

}

代码的作用是如果这个元素的属性不为空(hasAttribute&&(attributes!=null)),就把它们打印出来。

5characters(char[] ch,intlength) 处理元素字符的内容

public void characters(char[] ch,length));

}

我们只用了这么几个事件,其它还有其的的一些事件,我们只要看一下ContentHandler这个接口就行了,如:

6startPrefixMapping(String prefix,StringURI) 处理前缀映射开始事件,参数表示前缀名称和所指向的URI

7endPrefixMapping(String prefix,StringURI) 处理前缀映射结束事件,参数表示前缀名称和所指向的URI

8ignorableWhitespace(Char[] ch,intlength) 处理元素中可忽略的空格

9processingInstruction(String target,Stringdata) 处理解析中产生的处理指令事件。

至此SAX解析XML文档的大概介绍完了!

猜你在找的XML相关文章