接着,我们就来以“暴力“区分标签名的办法把数据映射到不同的对象:
import org.xml.sax.*; import org.xml.sax.helpers.*; import java.io.*; import java.util.*; import common.*;
public class Example5 extends DefaultHandler {
// 借肋用于捕获某个标签内容的标志。 private boolean inCircle = false; private boolean inTriangle = false; private boolean inSquare = false;
// 不同形体的本地向量表... private Vector triangles = new Vector(); private Vector squares = new Vector(); private Vector circles = new Vector();
// 当前形体的本地引用... private Triangle currentTriangle; private Circle currentCircle; private Square currentSquare;
// 从"characters" SAX事件中收集数据的缓存。 private CharArrayWriter contents = new CharArrayWriter();
// 重载DefaultHandler类以拦截SAX事件的方法。 // // 头于所有有效事件的详细内容,参见org.xml.sax.ContentHandler。 // public void startElement( String namespaceURI, String localName, String qName, Attributes attr ) throws SAXException {
contents.reset();
if ( localName.equals( "Circle" ) ) { inCircle = true; currentCircle = new Circle(); currentCircle.name = attr.getValue( "name" ); circles.addElement( currentCircle ); }
if ( localName.equals( "Square" ) ) { inSquare = true; currentSquare = new Square(); currentSquare.name = attr.getValue( "name" ); squares.addElement( currentSquare ); }
if ( localName.equals( "Triangle" ) ) { inTriangle = true; currentTriangle = new Triangle(); currentTriangle.name = attr.getValue( "name" ); triangles.addElement( currentTriangle ); }
}
public void endElement( String namespaceURI, String localName, String qName ) throws SAXException {
if ( localName.equals( "x" ) ) { if ( inCircle ) { currentCircle.x = Integer.valueOf (contents.toString().trim()).intValue(); } else if ( inSquare ) { currentSquare.x = Integer.valueOf (contents.toString().trim()).intValue(); } else { currentTriangle.x = Integer.valueOf (contents.toString().trim()).intValue(); } }
if ( localName.equals( "y" ) ) { if ( inCircle ) { currentCircle.y = Integer.valueOf (contents.toString().trim()).intValue(); } else if ( inSquare ) { currentSquare.y = Integer.valueOf (contents.toString().trim()).intValue(); } else { currentTriangle.y = Integer.valueOf (contents.toString().trim()).intValue(); } }
if ( localName.equals( "width" ) ) { if ( inCircle ) { currentCircle.width = Integer.valueOf (contents.toString().trim()).intValue(); } else if ( inSquare ) { currentSquare.width = Integer.valueOf (contents.toString().trim()).intValue(); } else { currentTriangle.width = Integer.valueOf (contents.toString().trim()).intValue(); } }
if ( localName.equals( "height" ) ) { if ( inCircle ) { currentCircle.height = Integer.valueOf (contents.toString().trim()).intValue(); } else if ( inSquare ) { currentSquare.height = Integer.valueOf (contents.toString().trim()).intValue(); } else { currentTriangle.height = Integer.valueOf (contents.toString().trim()).intValue(); } }
if ( localName.equals( "Circle" ) ) { inCircle = false; }
if ( localName.equals( "Square" ) ) { inSquare = false; }
if ( localName.equals( "Triangle" ) ) { inTriangle = false; }
}
public void characters( char[] ch, int start, int length ) throws SAXException { // 将数据内容写入缓存。 contents.write( ch, start, length );
}
public Vector getCircles() { return circles; }
public Vector getSquares() { return squares; }
public Vector getTriangles() { return triangles; }
public static void main( String[] argv ){
System.out.println( "Example5:" ); try {
// 创建SAX 2解析器... XMLReader xr = XMLReaderFactory.createXMLReader();
// 安装ContentHandler... Example5 ex5 = new Example5(); xr.setContentHandler( ex5 );
// 解析文件... xr.parse( new InputSource( new FileReader( "Example5.xml" )) );
// 将圆形对象显示到标准输出... Circle c; Vector items = ex5.getCircles(); Enumeration e = items.elements(); while( e.hasMoreElements()){ c = (Circle) e.nextElement(); c.print( System.out ); }
// 将长方形对象显示到标准输出... Square s; items = ex5.getSquares(); e = items.elements(); while( e.hasMoreElements()){ s = (Square) e.nextElement(); s.print( System.out ); }
// 将三角形对象显示到标准输出... Triangle t; items = ex5.getTriangles(); e = items.elements(); while( e.hasMoreElements()){ t = (Triangle) e.nextElement(); t.print( System.out ); }
}catch ( Exception e ) { e.printStackTrace(); }
}
}
下面是我们收集到我们的形体类中的数据对应的输出:
Example5: Circle: circ1 x: 10 y: 10 width: 3 height: 3 Square: sq1 x: 0 y: 0 width: 3 height: 3 Triange: tri1 x: 3 y: 0 width: 5 height: 3 Triange: tri2 x: 5 y: 0 width: 5 height: 3
第二个方案利用了你可以在运行时替换SAX 解析器的 SAX Content这一点。这就允许我们将映射任务分解成一个个小模块。我们可以把映射代码实现到某一XML文档的特定片段。
第二个例子中的endElement()没有用到嵌套的 if语句。这种模块化的设计在处理更加复杂的XML文档时尤其有效。这种方式同时也解决了XML文档中不可预测地出现的重复标签。
虽然第二个办法因为大多数类定义的重复出现而略显臃肿,这种更换ContentHandler类的方法却是走向一种更一般的SAX解析方法的第一步。替换ContentHandler也是另一个在SAX解析器的龙头下轮换啤酒杯(译注: Robert 极可能是个大肚皮形象: - ) )的方法。 
|