首先,先给出一个比较基本的处理xml文件的程序。你不必细看,直接跳过即可。需要时可以返回来看。
echo01.java
import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.defaulthandler;
import javax.xml.parsers.saxparserfactory;
import javax.xml.parsers.parserconfigurationexception;
import javax.xml.parsers.saxparser;
public class echo01 extends defaulthandler
{
stringbuffer textbuffer;
public static void main(string argv[])
{
if (argv.length != 1) {
system.err.println("usage: cmd filename");
system.exit(1);
}
// use an instance of ourselves as the sax event handler
defaulthandler handler = new echo01();
// use the default (non-validating) parser
saxparserfactory factory = saxparserfactory.newinstance();
try {
// set up output stream
out = new outputstreamwriter(system.out, "utf-8");
// parse the input
saxparser saxparser = factory.newsaxparser();
saxparser.parse( new file(argv[0]), handler);
} catch (throwable t) {
t.printstacktrace();
}
system.exit(0);
}
static private writer out;
//===========================================================
// sax documenthandler methods
//===========================================================
public void startdocument()
throws saxexception
{
emit("");
nl();
}
public void enddocument()
throws saxexception
{
try {
nl();
out.flush();
} catch (ioexception e) {
throw new saxexception("i/o error", e);
}
}
public void startelement(string namespaceuri,
string sname, // simple name
string qname, // qualified name
attributes attrs)
throws saxexception
{
echotext();
string ename = sname; // element name
if ("".equals(ename)) ename = qname; // not namespaceaware
emit("<"+ename);
if (attrs != null) {
for (int i = 0; i < attrs.getlength(); i++) {
string aname = attrs.getlocalname(i); // attr name
if ("".equals(aname)) aname = attrs.getqname(i);
emit(" ");
emit(aname+"=/""+attrs.getvalue(i)+"/"");
}
}
emit(">");
}
public void endelement(string namespaceuri,
string sname, // simple name
string qname // qualified name
)
throws saxexception
{
echotext();
string ename = sname; // element name
if ("".equals(ename)) ename = qname; // not namespaceaware
emit("");
}
public void characters(char buf[], int offset, int len)
throws saxexception
{
string s = new string(buf, offset, len);
if (textbuffer == null) {
textbuffer = new stringbuffer(s);
} else {
textbuffer.append(s);
}
}
//===========================================================
// utility methods ...
//===========================================================
// display text accumulated in the character buffer
private void echotext()
throws saxexception
{
if (textbuffer == null) return;
string s = ""+textbuffer;
emit(s);
textbuffer = null;
}
// wrap i/o exceptions in sax exceptions, to
// suit handler signature requirements
private void emit(string s)
throws saxexception
{
try {
out.write(s);
out.flush();
} catch (ioexception e) {
throw new saxexception("i/o error", e);
}
}
// start a new line
private void nl()
throws saxexception
{
string lineend = system.getproperty("line.separator");
try {
out.write(lineend);
} catch (ioexception e) {
throw new saxexception("i/o error", e);
}
}
}
从程序中可以看出,解析一个xml文件的核心语句是下面一部分:
// use an instance of ourselves as the sax event handler
defaulthandler handler = new echo01();
// use the default (non-validating) parser
saxparserfactory factory = saxparserfactory.newinstance();
try {
// set up output stream
out = new outputstreamwriter(system.out, "utf-8");
// parse the input
saxparser saxparser = factory.newsaxparser();
saxparser.parse( new file(argv[0]), handler);
} catch (throwable t) {
t.printstacktrace();
}
先是创建一个saxparserfactory工厂类的实例,然后通过saxparser saxparser = factory.newsaxparser(); 这个工厂类的方法创建了一个saxparser。将xml文件(new file(argv[0]))和一个sax event handler(handler)(在这个程序里面,这个handler其实是本身这个类,这个类继承了org.xml.sax.helpers.defaulthandler 这个类,并且在前面初始化了它:defaulthandler handler = new echo01(); )传递给它,让它进行解析。
关于xml文件的解析过程中的处理全部在handler里面实现。一般parser接受的是defaulthandler或者handlerbase这两个类。 这个例子里面的类是继承defaulthandler这个虚类的。看下图:

而defaulthandler是实现了entityresolver, dtdhandler, contenthandler, errorhandler四个接口的虚类。分别定义了如下的方法:

不同的方法,在不同的时候被parser调用,(这个不同的时候就是event-based)
详细介绍:(暂略)
defualthandler的uml图如下:
闽公网安备 35060202000074号