SAX(Simple API for XML用于XML的简单API)
由于提前学习了cocoon,时间上又经过了一个周末,想要写得激情没有剩下多少,这里简单的回顾一下SAX的一些接口定义和用处吧!-_-#
1、准备工作
sax相关的类都封装在org.xml.sax中,其中接口org.xml.sax.XMLReader是SAX2的核心类,你的xml解析器应该提供这个接口的实现类。比如"org.apache.xerces.parsers.SAXParser"这个类。
2、sax的处理流程
sax基本的处理方法是在解析之前注册各种处理类(Handler),在解析的时候callback这些处理器,内容处理器就是其中最主要的一个。举例来说明的话,如下的xml文档:
<?
xml version="1.0"
?>
<
samples
>
<
server
>
UNIX
</
server
>
<
monitor
>
color
</
monitor
>
</
samples
>
他将会在解析的时候被转化成如下的一串事件流:
Start document
Start element (samples)
Characters (white space)
Start element (server)
Characters (UNIX)
End element (server)
Characters (white space)
Start element (monitor)
Characters (color)
End element (monitor)
Characters (white space)
End element (samples)
开发者要做的就是捕获这些事件,然后做自己要做的事情。
3、内容处理类
org.xml.sax.ContentHandler
package org.xml.sax;
public
interface
ContentHandler
{
public void setDocumentLocator (Locator locator);
public void startDocument ()throws SAXException;
public void endDocument()throws SAXException;
public void startPrefixMapping (String prefix, String uri) throws SAXException;
public void endPrefixMapping (String prefix)throws SAXException;
public void startElement (String namespaceURI, String localName,String qName, Attributes atts)
throws SAXException;
public void endElement (String namespaceURI, String localName,String qName)throws SAXException;
public void characters (char ch[], int start, int length)throws SAXException;
public void ignorableWhitespace (char ch[], int start, int length)throws SAXException;
public void processingInstruction (String target, String data)throws SAXException;
public void skippedEntity (String name)throws SAXException;
}
有一点要说明的就是ignorableWhitespace 这个方法是在遇到
可以忽略的空白的时候回调的,但是如果xml文档没有定义DTD或者是Schema,那么这个方法将不会被调用,因为如果没有文档结构的定义,解析器又如何判断哪些空白是
可以忽略的呢。
4、错误处理类
ErrorHandler这个类提供两个方法,warning和error,用于在处理解析过程发生的错误和警告,包括xml格式的错误和文档结构检查的错误。
5、过滤器和写入器
org.xml.sax.XMLFilter这个接口扩展了XMLReader接口,添加了两个新方法:
public void setParent(XMLReader reader);
public XMLReader getParent();
他的意图比较明显,将一个已有的XMLReader作为上级解析器,他将得以在这个XMLReader执行捕获sax事件之前捕获他们,并作一些操作,最后在链向XMLReader的对象,这里的概念很像cocoon的内部实现。
这里还要提到的一个类是:org.xml.sax.helpers.XMLFilterImpl这个类实现了XMLFilter接口,不仅如此,他还提供了ContentHandler,ErrorHandler等处理器的处理方法通道。也就是说,如果继承XMLFilterImpl并覆盖startElement方法,那么你写得代码将在实际的Reader执行startElement方法被执行之前被执行。下面是一个注册Filter的例子:
XMLReader reader
=
XMLReaderFactory.createXMLreader();
MyFilter filter
=
new
MyFilter(reader.);
filter.setContenHandler();
注意在注册内容处理类等类的时候,应该写filter....
另外,你当然也可以再写一个filter2,而把filter作为parent传入,这样就构成了一个事件处理链。
org.xml.sax.XMLWriter是一个实际的过滤器,他也是通过上面说到的方式:扩展XMLFilterImpl来实现的。具体的类除了XMLWriter外还有DataWriter,他扩展XMLWriter。
需要注意的是这两个类一般不用来做实际的写入流操作,但是他们可以用于很好的表现sax处理链的中间结果,也就是快照snapshot
6、sax的属性和特征
属性和特征在XMLReader接口里面体现为:
getFeature(String),setFeature(String,boolean)方法和getProperty(String),setProperty(String,Object)方法,用来控制解析过程的一些选项,比如是否进行DTD校验。比如:
reader.setFeature("
http://xml.org/sax/features/validation", true);这样会在解析的时候校验DTD定义
reader.setFeature("
http://apache.org/xml/features/validation/schema", true);这样会启动schema校验。