站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题SAX之Java实现学习笔记(一)

SAX之Java实现学习笔记(一)

摘要:

from jzk的blog: http://www.matrix.org.cn/blog/jzk
本文假设读者对
XML有些了解<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


&nbsp;


首先,先给出一个比较基本的处理xml文件的程序。你不必细看,直接跳过即可。需要时可以返回来看。


&nbsp;


&nbsp;


Echo01.java


&nbsp;


import java.io.*;


&nbsp;


import org.xml.sax.*;


import org.xml.sax.helpers.DefaultHandler;


&nbsp;


import javax.xml.parsers.SAXParserFactory;


import javax.xml.parsers.ParserConfigurationException;


import javax.xml.parsers.SAXParser;


&nbsp;


public class Echo01 extends DefaultHandler


{


&nbsp;&nbsp;&nbsp; StringBuffer textBuffer;


&nbsp;


&nbsp;&nbsp;&nbsp; public static void main(String argv[])


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (argv.length != 1) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("Usage: cmd filename");


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(1);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Use an instance of ourselves as the SAX event handler


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DefaultHandler handler = new Echo01();


&nbsp;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Use the default (non-validating) parser


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXParserFactory factory = SAXParserFactory.newInstance();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set up output stream


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out = new OutputStreamWriter(System.out, "UTF-8");


&nbsp;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Parse the input


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXParser saxParser = factory.newSAXParser();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; saxParser.parse( new File(argv[0]), handler);


&nbsp;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable t) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t.printStackTrace();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(0);


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; static private Writer&nbsp; out;


&nbsp;


&nbsp;&nbsp;&nbsp; //===========================================================


&nbsp;&nbsp;&nbsp; // SAX DocumentHandler methods


&nbsp;&nbsp;&nbsp; //===========================================================


&nbsp;


&nbsp;&nbsp;&nbsp; public void startDocument()


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit("<?xml version='1.0' encoding='UTF-8'?>");


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nl();


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; public void endDocument()


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nl();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.flush();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new SAXException("I/O error", e);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; public void startElement(String namespaceURI,


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String sName, // simple name


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String qName, // qualified name


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attributes attrs)


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echoText();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String eName = sName; // element name


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ("".equals(eName)) eName = qName; // not namespaceAware


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit("&lt;"+eName);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attrs != null) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; attrs.getLength(); i++) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String aName = attrs.getLocalName(i); // Attr name


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ("".equals(aName)) aName = attrs.getQName(i);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit(" ");


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit(aName+"=\""+attrs.getValue(i)+"\"");


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit("&gt;");


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; public void endElement(String namespaceURI,


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sName, // simple name


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String qName&nbsp; // qualified name


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echoText();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String eName = sName; // element name


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ("".equals(eName)) eName = qName; // not namespaceAware


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit("");


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; public void characters(char buf[], int offset, int len)


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = new String(buf, offset, len);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (textBuffer == null) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textBuffer = new StringBuffer(s);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textBuffer.append(s);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; //===========================================================


&nbsp;&nbsp;&nbsp; // Utility Methods ...


&nbsp;&nbsp;&nbsp; //===========================================================


&nbsp;


&nbsp;&nbsp;&nbsp; // Display text accumulated in the character buffer


&nbsp;&nbsp;&nbsp; private void echoText()


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (textBuffer == null) return;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = ""+textBuffer;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit(s);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textBuffer = null;


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; // Wrap I/O exceptions in SAX exceptions, to


&nbsp;&nbsp;&nbsp; // suit handler signature requirements


&nbsp;&nbsp;&nbsp; private void emit(String s)


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.write(s);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.flush();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new SAXException("I/O error", e);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp; }


&nbsp;


&nbsp;&nbsp;&nbsp; // Start a new line


&nbsp;&nbsp;&nbsp; private void nl()


&nbsp;&nbsp;&nbsp; throws SAXException


&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String lineEnd =&nbsp; System.getProperty("line.separator");


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;try {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.write(lineEnd);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new SAXException("I/O error", e);


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp; }


}


&nbsp;


从程序中可以看出,解析一个XML文件的核心语句是下面一部分:


&nbsp;&nbsp;&nbsp;&nbsp; // Use an instance of ourselves as the SAX event handler


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DefaultHandler handler = new Echo01();


&nbsp;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Use the default (non-validating) parser


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXParserFactory factory = SAXParserFactory.newInstance();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set up output stream


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out = new OutputStreamWriter(System.out, "UTF-8");


&nbsp;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Parse the input


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXParser saxParser = factory.newSAXParser();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; saxParser.parse( new File(argv[0]), handler);


&nbsp;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable t) {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t.printStackTrace();


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


先是创建一个SAXParserFactory工厂类的实例,然后通过SAXParser saxParser = factory.newSAXParser(); 这个工厂类的方法创建了一个saxParser。将xml文件(new File(argv[0]))和一个Sax Event Handlerhandler)(在这个程序里面,这个Handler其实是本身这个类,这个类继承了org.xml.sax.helpers.DefaultHandler 这个类,并且在前面初始化了它:DefaultHandler handler = new Echo01();&nbsp; )传递给它,让它进行解析。


&nbsp;


关于xml文件的解析过程中的处理全部在Handler里面实现。一般Parser接受的是DefaultHandler或者HandlerBase这两个类。 这个例子里面的类是继承DefaultHandler这个虚类的。看下图:


&nbsp;


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


&nbsp;


DefaultHandler是实现了EntityResolver, DTDHandler, ContentHandler, ErrorHandler四个接口的虚类。分别定义了如下的方法:


&nbsp;



&nbsp;


不同的方法,在不同的时候被Parser调用,(这个不同的时候就是Event-based


详细介绍:(暂略)


&nbsp;


&nbsp;


DefualtHandlerUML图如下:



&nbsp;


&nbsp;


看完Handler,再转过头去看Parser,在代码里面用的是SAXParser(SAXParser saxParser)


仔细看里面的代码



&nbsp;



你会发现,其实它并没有自己完成解析的工作,而是Wrap了另二个类XMLReaderParser来完成解析工作。原来SAXParser只是起到一个Adapter的工作而已。


&nbsp;


UML:



&nbsp;


&nbsp;


↑返回目录
前一篇: SAX之Java实现学习笔记(二)
后一篇: JDO2.0的查询语言新特性