ContentHandler是Java类包中一个特殊的SAX接口,位于org.xml.sax包中。该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件,比如文档的开头和结束、元素开头和结束、以及元素中的字符数据等事件。当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件。ContentHandler接口的方法有以下几种:
l void startDocument()方法:接收文档开始的通知,SAX解析器仅调用该方法一次。
l void endDocument()方法:接收文档结尾的通知,SAX解析器仅调用该方法一次,并且它将是解析期间最后调用的方法。直到解析器放弃解析(由于不可恢复的错误)或到达输入的结尾时,该方法才会被调用。
l void startElement(String uri, String localName, String qName, Attributes atts)方法:接收元素开始的通知。该方法的参数信息如下:
uri:名称空间URI,如果元素没有名称空间URI,如果未执行名称空间处理,则为空字符串。
localName:本地名称(不带前缀),如果未执行命名空间处理,则为空字符串。
qName:元素名(带有前缀),如果元素名不可用,则为空字符串。
atts:该元素的属性。如果没有属性,则它将是空Attributes对象。在startElement返回后,此对象的值是未定义的。
l void endElement(String uri, String localName, String qName)方法:接收元素结束的通知。该方法的参数含义与startElement()方法的参数含义一致。
l void characters(char[ ] ch, int start, int length)方法:接收字符数据的通知。该方法的参数信息如下:
ch:字符数组,来自XML文档中的字符串数据。
start:数组中的开始位置
length:从数组中读取的字符的个数
l void ignorableWhitespace(char[ ] ch, int start, int length)方法:接收元素内容中可忽略的空白通知。该方法的参数含义与characters()方法的参数含义一致。
l void startPrefixMapping(String prefix, String uri)方法:开始标记的前缀URI名称空间范围映射。该方法的参数信息如下:
prefix:声明的名称空间前缀。对于没有前缀的默认元素名称空间,使用空字符串。
uri:将前缀映射到的名称空间URI。
l void endPrefixMapping(String prefix)方法:结束标记的前缀URI名称空间范围的映射。
l void setDocumentLocator(Locator locator)方法:接收用来查找SAX文档事件起源的对象。如果要使用SAX解析器来提供定位器,则必须在调用ContentHandler接口中的任何其他方法之前调用该方法,为应用程序提供定位器。
l void ignorableWhitespace(char[ ] ch, int start, int length)方法:接收元素内容中可忽略的空白的通知。
l void processingInstruction(String target, String data)方法:接收处理指令的通知。
l void skippedEntity(String name)方法:接收跳过的实体的通知。
下面我们来看一个简单的例子:
SAXExample1.java
import org.xml.sax.*;
import org.xml.sax.ContentHandler;
public class SAXExample1 implements ContentHandler{
public void setDocumentLocator(Locator locator){
System.out.println(”执行setDocumentLocator()方法!!“);
}
public void startDocument( ) throws SAXException{
System.out.println(”执行startDocument( )方法!!“);
}
public void endDocument() throws SAXException{
System.out.println(”执行endDocument( )方法!!“);
}
public void startPrefixMapping(String prefix, String uri)
throws SAXException{
System.out.println(”执行startPrefixMapping( )方法!!“);
}
public void endPrefixMapping(String prefix) throws SAXException{
System.out.println(”执行endPrefixMapping( )方法!!“);
}
public void startElement(String uri, String localName,
String qName, Attributes atts) throws SAXException {
System.out.println(”执行startElement( )方法!!“);
}
public void endElement(String uri, String localName, String qName)
throws SAXException{
System.out.println(”执行endElement( )方法!!“);
}
public void characters(char[ ] ch, int start, int length)
throws SAXException{
System.out.println(”执行characters( )方法!!“);
}
public void ignorableWhitespace(char[ ] ch, int start, int length)
throws SAXException{
System.out.println(”执行ignorableWhitespace( )方法!!“);
}
public void processingInstruction(String target, String data)
throws SAXException{
System.out.println(”执行processingInstruction( )方法!!“);
}
public void skippedEntity(String name) throws SAXException{
System.out.println(”执行skippedEntity( )方法!!“);
}
}
在例中SAXExample1类实现了ContentHandler接口,并重写了该接口的所有方法。但在这些方法中,我们采取了简单的实现。主要是想让大家了解这些方法的执行顺序和过程。
然后创建一个简单的XML文档,XML文档(test1.xml)代码如下:
<?xml version=”1.0″ encoding=”UTF-8″?>
<student id=”a001″>
this is a test
<name>zhangsan</name>
</student>
最后再做一个测试类(TestSax.java)用来创建解析器,并将这些事件处理程序分配给该解析器,程序代码如下:
import org.xml.sax.*;
import org.xml.sax.helpers.*;
public class TestSax{
public static void main(String args[ ]){
try {
// 建立SAX 2解析器...
XMLReader parser=XMLReaderFactory.createXMLReader();
// 安装ContentHandler...
parser.setContentHandler(new SAXExample1());
//解析文件...
parser.parse(”test1.xml”);
}catch ( Exception e ) {
e.printStackTrace();
}
}
}
SAXExample2.java
import org.xml.sax.*;
import java.io.*;
import org.xml.sax.ContentHandler;
public class SAXExample2 implements ContentHandler{
public void setDocumentLocator(Locator locator){
System.out.println(”查找文档完成!“);
}
public void startDocument() throws SAXException{
System.out.println(”开始解析!“);
}
public void endDocument() throws SAXException{
System.out.println(”解析完成!“);
}
public void startPrefixMapping(String prefix, String uri)
throws SAXException{
System.out.println(”执行startPrefixMapping()方法!!“);
}
public void endPrefixMapping(String prefix) throws SAXException{
System.out.println(”执行endPrefixMapping()方法!!“);
}
public void startElement(String uri, String localName,
String qName, Attributes atts) throws SAXException {
System.out.println(”元素名:“+qName);
for(int i=0;i<atts.getLength();i++){
System.out.print(” “);
System.out.println(”属性:“+atts.getQName(i)
+”=”+atts.getValue(i));
}
System.out.print(”字符数据为:“);
}
public void endElement(String uri, String localName,
String qName) throws SAXException{
System.out.println(”对“+qName+”的解析完成!“);
}
public void characters(char[ ] ch, int start, int length)
throws SAXException{
try {
OutputStreamWriter outw =
new OutputStreamWriter(System.out);
outw.write(ch,start,length);
outw.flush();
System.out.println(”");
}catch (Exception e) {
e.printStackTrace();
}
}
public void ignorableWhitespace(char[ ] ch, int start, int length)
throws SAXException{
System.out.println(”执行ignorableWhitespace()方法!!“);
}
public void processingInstruction(String target, String data)
throws SAXException{
System.out.println(”执行processingInstruction()方法!!“);
}
public void skippedEntity(String name) throws SAXException{
System.out.println(”执行skippedEntity()方法!!“);
}
}