在j2ee1.4標(biāo)準(zhǔn)教材里看到一個(gè)很有趣的例子,從任意數(shù)據(jù)結(jié)構(gòu)生成XML解析器產(chǎn)生SAX事件.數(shù)據(jù)結(jié)構(gòu)可以是文本文件,PDF格式文檔等.關(guān)鍵是自己解析這些數(shù)據(jù)源.另外一個(gè)有意思的地方是觀察者模式的應(yīng)用.所以就粗糙的改了一下并完整到可以測(cè)試運(yùn)行.觀察者模式簡(jiǎn)略UML圖:

具體實(shí)現(xiàn) 被觀察者對(duì)象ParseXMLSubject類:
package test;
import java.io.*;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.*;
public class ParseXMLSubject implements XMLReader {
??? ContentHandler handler;
??? String nsu = "";
??? Attributes atts = new AttributesImpl();
??? String rootElement = "addressbook";
??? String indent = "\n??? ";
??? public ParseXMLSubject(){
??? }
??? public ContentHandler getContentHandler() {
??????? return handler;
??? }
??? public void parse(InputSource input) throws IOException, SAXException {
??????? try {
??????????? // Get an efficient reader for the file
??????????? java.io.Reader r = input.getCharacterStream();
??????????? BufferedReader br = new BufferedReader(r);
??????????? // Read the file and display it's contents.
??????????? String line = br.readLine();
??????????? while (null != (line = br.readLine())) {
??????????????? if (line.startsWith("email:")) {
??????????????????? break;
??????????????? }
??????????? }
??????????? if (handler == null) {
??????????????? throw new SAXException("No content handler");
??????????? }
??????????? // Note:
??????????? // We're ignoring setDocumentLocator(), as well
??????????? handler.startDocument();
??????????? handler.startElement(nsu, rootElement, rootElement, atts);
??????????? output("email",? line);
??????????? line = br.readLine();
??????????? output("html", line);
??????????? line = br.readLine();
??????????? output("firstname",? line);
??????????? line = br.readLine();
??????????? output("lastname", line);
??????????? line = br.readLine();
??????????? output("work",? line);
??????????? line = br.readLine();
??????????? output("home", line);
??????????? line = br.readLine();
??????????? output("fax",? line);
??????????? line = br.readLine();
??????????? output("pager", line);
??????????? line = br.readLine();
??????????? output("cell",? line);
??????????? handler.ignorableWhitespace("\n".toCharArray(), 0, // start index
??????????????????????????????????????? 1 // length
??????????????????? );
??????????? handler.endElement(nsu, rootElement, rootElement);
??????????? handler.endDocument();
??????? } catch (Exception e) {
??????????? e.printStackTrace();
??????? }
??? }
??? public void parse(String systemId) throws IOException, SAXException {
??? }
??? public DTDHandler getDTDHandler() {
??????? return null;
??? }
??? public EntityResolver getEntityResolver() {
??????? return null;
??? }
??? public ErrorHandler getErrorHandler() {
??????? return null;
??? }
??? public boolean getFeature(String name) throws SAXNotRecognizedException,
??????????? SAXNotSupportedException {
??????? return false;
??? }
??? public Object getProperty(String name) throws SAXNotRecognizedException,
??????????? SAXNotSupportedException {
??????? return null;
??? }
??? public void setContentHandler(ContentHandler handler) {
??????? this.handler = handler;
??? }
??? public void setDTDHandler(DTDHandler handler) {
??? }
??? public void setEntityResolver(EntityResolver resolver) {
??? }
??? public void setErrorHandler(ErrorHandler handler) {
??? }
??? public void setFeature(String name, boolean value) throws
??????????? SAXNotRecognizedException, SAXNotSupportedException {
??? }
??? public void setProperty(String name, Object value) throws
??????????? SAXNotRecognizedException, SAXNotSupportedException {
??? }
??? void output(String name, String line) throws SAXException {
??????? int tmp = name.length();
??????? int startIndex=tmp+1;
??????? int textLength = line.length() - startIndex;
??????? String characters = line.substring(startIndex,line.length()-1);
??????? handler.ignorableWhitespace(indent.toCharArray(), 0, // start index
??????????????????????????????????? indent.length());
??????? handler.startElement(nsu, name, name /*"qName"*/, atts);
??????? handler.characters(characters.toCharArray(), startIndex, textLength);
??????? handler.endElement(nsu, name, name);
??? }
}
具體觀察者對(duì)象: ConcreateObserver類
package test;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.*;
public class ConcreateObserver extends DefaultHandler {
??? public ConcreateObserver() {
??? }
??? public void startElement(String uri,
???????????????????????? String localName,
???????????????????????? String qName,
???????????????????????? Attributes attributes)
????????????????? throws SAXException{
????????????? System.out.println("startElement: "+localName);
????????? }
????????? public void characters(char[] ch,
???????????????????????????????? int start,
???????????????????????????????? int length)
??????????????? throws SAXException{
??????????? System.out.println("characters: ");
??????????? System.out.print(ch);
??????????? System.out.println();
??????? }
}
測(cè)試類:TestMain
package test;
import java.io.*;
import org.xml.sax.InputSource;
public class TestMain {
??? public TestMain() {
??? }
??? public static void main(String[] args) throws Exception {
??????? TestMain testmain = new TestMain();
??????? FileReader in = new FileReader(new File("d:\\AddressBookReaderLog01.txt"));
??????? ConcreateObserver observer=new ConcreateObserver();
??????? ParseXMLSubject parse = new ParseXMLSubject();
??????? parse.setContentHandler(observer);
??????? parse.parse(new InputSource(in));
??? }
}
測(cè)試文本文檔:AddressBookReaderLog01.txt
AddressBookReader01 ../samples/PersonalAddressBook.ldif
nickname: Fred
email: fred@barneys.house
html: TRUE
firstname: Fred
lastname: Flintstone
work: 999-Quarry
home: 999-BedrockLane
fax: 888-Squawk
pager: 777-pager
cell: 555-cell
另外一個(gè)也比較也有意思的地方就是具體觀察者類從DefaultHandler 繼承,該類是缺省適配器模式的應(yīng)用.
歡迎加入QQ群:30406099?