使用AELFRED进行XML程序设计

-- 如何使用


  1. 简介
  2. 基本原理
  3. 如何使用
  4. 汉化
  5. Applet
  6. 杂项

AELFRED解析XML文件的基本过程为,首先要生成一个XmlParser的实例,并且为XmlParser提供一个XmlHandler,然后XmlParser读取一个XML文档,在XmlParser读取XML文档的过程中,如果XmlParser遇到不同的XML文档部分(元素,属性等等)时,XmlParser会调用XmlHandler中的相应方法。需要引起注意的是,同XERCES解析器不同,AELFRED不会把XML文档转换成一个树状的对象集合,而仅仅是线性地把XML文件读出来交给XmlHandler实现的代码来处理。下面一段代码展示了基本的程序构架。

XmlHandler handler = new MyHandler(); // MyHandler是自己定义的一个类,继承了HandlerBase或者实现了XmlHandler。 XmlParser parser = new XmlParser(); //创建解析器 parser.setHandler(handler); //为解析器设置处理器 try { parser.parse("http://www.host.com/doc.xml", null); //进行解析 } catch (Exception e) //错误处理 { }

在XmlHandler这个Interface中声明的方法如表1。当我们对文档进行处理时,我们需要实现这些方法来处理我们所遇到的个别的文档。

表1:XmlHandler中声明的方法
方法名 使用说明
attribute(String name, String value, boolean specific) 当XML文档中出现一个attribute时这个方法被调用。第一个参数是attribute的名字,第二参数是attribute的值,第三参数个表示是从xml文件中定义的还是从dtd中定义完成的。若如果为true则是从xml文档中定义,若为false则是dtd提供的缺省值。
charData(char[] array, int offset, int length) 当XML文档中出现字符串数据的时候这个方法被调用。第一个参数是包含字符串数据的字符数组,第二个参数是起始位置,第三个参数是长度。需要注意的是解析器可能把在一对tag内包含的字符串分成几个部分,连续调用charData方法若干次。
doctypeDecl(String name, String publicID, String systemID) 当遇到定义文件格式声明时这个方法被调用。第一个参数是文件类型名;第二个参数是public标识符,如果没有,那么为null;第三个参数为system标识符,如果没有,为null。
endDocument() 当XML文档结束的时候这个方法被调用,这个方法每处理一个XML文档仅仅会被调用一次。
endElement(String name) 当一个Element结束的时候这个方法被调用。参数为element的名字,即<>内的字符串。
endExternalEntity(String systemID) 外部文件结束时这个方法被调用。参数为外部文件的URI。
error(String message, String systemID, int line, int column) 当出现错误时aelfred调用这个方法。参数分别为错误信息,出错文件的URI,行,列。如果这个方法被调用了,那么aelfred可能不会停止解析过程,但是该文件肯定
ignorableWhitespace(char[] data, int offset, int length) 当出现可以被忽略的空格时这个方法被调用。第一个参数是包含空字符串数据的字符数组,第二个参数是起始位置,第三个参数是长度。
processingInstruction(String target, String data) 当在文档中遇到处理指令的时候,aelfred调用此方法。
resolveEntity(String publicID, String systemID ) 当处理外部文档时这个方法被调用。在这里可以校验不正确的URI,还可以转移到自己预定的文件上。
startDocument() 当文档开始时这个方法被调用,这个方法仅会被调用一次。
startElement(String name) 当一个Element开始时这个方法被调用。参数为element的名字。
startExternalEntity(String systemID) 当外部dtd文件开始时这个方法被调用。

对于不需要处理所有XML元素的情况下,我们可以通过继承HandlerBase类的方法来生成自己的处理器。下面一段代码展示了如何使用继承HandlerBase的方法进行XML工作。

import com.microstar.xml.*; import java.io.*; public class MainTest1 { public static void main(String[] x) { FileReader fReader = null; try { fReader = new FileReader("test.xml");//读文件 } catch( IOException e) { e.printStackTrace(); } XmlHandler handler = new test1Handler();//创建handler XmlParser parser = new XmlParser();//创建parser parser.setHandler(handler);//为parser设置handler try { parser.parse(null, null, fReader);//解析 } catch (Exception e) { e.printStackTrace();//错误处理 } } } class test1Handler extends HandlerBase //继承了HandlerBase,这里还可以使用 // implements XmlHandler的办法。 { int space = 0; //constructor test1Handler() { super(); } //下面是输出空格用的函数。 void outputSpace() { for(int i = 0 ; i < space ; i ++ ) { System.out.print("\t"); } } //文档开始的时候调用这个函数。 public void startDocument() { System.out.println("StartDocument"); } //文档结束的时候调用这个函数。 public void endDocument() { System.out.println("EndDocument"); } // public Object resolveEntity (String publicId, String systemId) { outputSpace(); System.out.println("resolving Entity==>"+publicId+";"+systemId); return null; } //外部文档开始时调用这个方法。 public void startExternalEntity (String systemId) { space++; outputSpace(); System.out.println("starting External Entity:"+systemId); } //外部文档结束的时候调用这个方法。 public void endExternalEntity (String systemId) { outputSpace(); space--; System.out.println("ending External Entity:"+systemId); } //文档声明开始 public void doctypeDecl (String name, String pubid, String sysid) { outputSpace(); System.out.println("doctypeDecl==>"+pubid+";"+sysid); } //属性开始时调用这个方法。 public void attribute (String name, String value, boolean isSpecified) { outputSpace(); System.out.println("attribute:"+name+"="+value); } //element开始的时候调用这个方法。 public void startElement (String name) { space++; outputSpace(); System.out.println("startElement:"+name); } //element结束的时候调用这个方法。 public void endElement (String name) { outputSpace(); System.out.println("endElement:"+name); space--; } //字符串内容,就是文档的实际内容会调用这个方法。 public void charData (char ch[], int start, int length) { String data = new String ( ch , start , length ); if( data.equals("\n")|| data.equals("\r")|| data.equals("\n\r")||data.equals("\n\t")) { outputSpace(); System.out.println("return"); } else { outputSpace(); System.out.println("charData:"+data+";length="+length); } } //遇到没有用的空格之类的内容的时候调用这个方法。 public void ignorableWhitespace (char ch[], int start, int length) { outputSpace(); System.out.println("\twhite spaces!"); } }

用来解析的xml文件如下

<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE test [ <!ELEMENT test (test1,test2)> ]> <!-- <!DOCTYPE test SYSTEM "http://127.0.0.1/mytest/mytest.dtd"> --> <test> <test1 id="testone"/> <test2>testtwo你好&lt;</test2 > </test>

相关的dtd文件如下

<?xml version="1.0" encoding="GB2312"?> <!ELEMENT test (test1,test2)+> <!ELEMENT test2 ANY> <!ELEMENT test1 EMPTY> <!ATTLIST test1 id CDATA #REQUIRED name CDATA #REQUIRED>

输出结果如下

当xml文件使用外部dtd文件时,测试程序的输出结果如下

这个测试在windows 98,Apache1.3.9, Tomcat 3.2, jdk1.2, jdk1.3环境下运行通过。