一列简单的Java对象 对于更加复杂的XML文档,我们需要映射一系列的对象到Java。映射一系列对象就像做酒吧服务生一样:当一个服务生要倒满一排啤酒时,他通常让酒桶龙头一直开着,他则只是讯速地把杯子依次接到龙头下面。这正是我们捕获一系列对象时所要做的。我们无法控制到来的SAX事件;它们就像不能关闭的龙头里流出来的啤酒一样。为了解决问题,我们需要提供空的容器,让它们充满,不停的替换它们。 
我们下一个例子说明这一技术。用一个XML文档表示一个虚拟的定购客户,我们将把代表一系列定购商品的XML映射到一个Java的定购商品向量表中。实现这一想法的关键是“当前的商品”。每次我们得到一个事件表明一件新的定购商品(OrderItem标签的startElement),我们就创建一个空的order-item对象,将它加入定购商品列表中,并以它为当前定购商品。余下的工作由XML解析器完成。 
首先,这里有代表我们的虚拟顾客的XML文档: 
 <?xml version="1.0"?> <CustomerOrder>    <Customer>       <FirstName> Bob </FirstName>       <LastName> Hustead </LastName>       <CustId> abc.123 </CustId>    </Customer>    <OrderItems>       <OrderItem>          <Quantity> 1 </Quantity>               <ProductCode> 48.GH605A </ProductCode>          <Description> Pet Rock </Description>          <Price> 19.99 </Price>       </OrderItem>       <OrderItem>          <Quantity> 12 </Quantity>               <ProductCode> 47.9906Z </ProductCode>          <Description> Bazooka Bubble Gum </Description>          <Price> 0.33 </Price>       </OrderItem>       <OrderItem>          <Quantity> 2 </Quantity>               <ProductCode> 47.7879H </ProductCode>          <Description> Flourescent Orange Squirt Gun </Description>          <Price> 2.50 </Price>       </OrderItem>    </OrderItems> </CustomerOrder> 
又是我们的简单顾客类: 
 package common;
  import java.io.*;
 
  // Customer是一个包含一名虚拟顾客的属性的简单类。 // 它有一个简单的方法把自已打印到一个打印流。
  public class Customer {
    // Customer成员变量    public String firstName = "";    public String lastName  = "";    public String custId    = "";
          public void print( PrintStream out ) {             out.println( "Customer: " );             out.println( "  First Name -> "  + firstName );             out.println( "  Last Name -> "   + lastName  );             out.println( "  Customer Id -> " + custId    );    }
  } 
Next, a simple class to represent an order item:  
 package common;
  import java.io.*;
 
  // Customer是一个包含一名虚拟顾客的属性的简单类。 // 它有一个简单的方法把自已打印到一个打印流。
  public class OrderItem {
     // OrderItem member variables.    public int    quantity     = 0;    public String productCode  = "";    public String description  = "";    public double price        = 0.0;
 
          public void print( PrintStream out ) {             out.println( "OrderItem: " );             out.println( "  Quantity -> "  + Integer.toString(quantity) );             out.println( "  Product Code -> "   + productCode  );             out.println( "  Description -> " + description    );             out.println( "  price -> " + Double.toString( price )    );
     }
  } 
现在,我们把注意力转移到SAX解析器例四,它将映射顾客和商品: 
 import org.xml.sax.*; import org.xml.sax.helpers.*; import java.io.*; import java.util.*; import common.*;
  public class Example4 extends DefaultHandler {
 
    // 用于收集customer的XML数据的本地Customer变量    private  Customer cust = new Customer();
     // 定购对象的本地向量表...    private Vector orderItems = new Vector();
     // 当前定购对象的本地引用...    private OrderItem currentOrderItem;
    // 用于从"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( "OrderItem" ) ) {                    currentOrderItem = new OrderItem();          orderItems.addElement( currentOrderItem );       }
     }
     public void endElement( String namespaceURI,                String localName,               String qName ) throws SAXException {
        if ( localName.equals( "FirstName" ) ) {          cust.firstName = contents.toString();       }
        if ( localName.equals( "LastName" ) ) {          cust.lastName = contents.toString();       }
        if ( localName.equals( "CustId" ) ) {          cust.custId = contents.toString();       }
        if ( localName.equals( "Quantity" ) ) {          currentOrderItem.quantity = Integer.valueOf(contents.toString().trim()).intValue();       }
        if ( localName.equals( "ProductCode" ) ) {          currentOrderItem.productCode = contents.toString();       }
        if ( localName.equals( "Description" ) ) {          currentOrderItem.description = contents.toString();       }
        if ( localName.equals( "Price" ) ) {          currentOrderItem.price = Double.valueOf(contents.toString().trim()).doubleValue();       }
 
     }
     public void characters( char[] ch, int start, int length )                   throws SAXException {
           contents.write( ch, start, length );
     }
 
     public Customer getCustomer()  {            return cust;    }
     public Vector getOrderItems() {            return orderItems;    }
     public static void main( String[] argv ){
        System.out.println( "Example4:" );       try {
          // 创建SAX 2解析器...          XMLReader xr = XMLReaderFactory.createXMLReader();
          // 安装ContentHandler...          Example4 ex4 = new Example4();          xr.setContentHandler( ex4 );
          // 解析文件...          xr.parse( new InputSource(                new FileReader( "Example4.xml" )) );
          // 将customer显示到标准输出...          Customer cust = ex4.getCustomer();          cust.print( System.out );
           // 把所有的定购商品显示到标准输出...          OrderItem i;          Vector items = ex4.getOrderItems();          Enumeration e = items.elements();          while( e.hasMoreElements()){                            i = (OrderItem) e.nextElement();             i.print( System.out );          }
 
        }catch ( Exception e )  {          e.printStackTrace();       }
 
     }
  } 
这里是我们的Customer与OrderItems对象产生的输出: 
 Example4: Customer:   First Name ->  Bob   Last Name ->  Hustead   Customer Id ->  abc.123 OrderItem:   Quantity -> 1   Product Code ->  48.GH605A   Description ->  Pet Rock   price -> 19.99 OrderItem:   Quantity -> 12   Product Code ->  47.9906Z   Description ->  Bazooka Bubble Gum   price -> 0.33 OrderItem:   Quantity -> 2   Product Code ->  47.7879H   Description ->  Fluorescent Orange Squirt Gun   price -> 2.5 
当XML文档的结构变得更复杂时,真正的因难是管理创建用于容纳SAX 事件所产生的数据流的空对象。对于简单的对象容器,这个管理工作并不复杂。但是,我们正是要开发一种复杂嵌套的容器,比方容器的容器和包含拥有容器成员对象的容器。 
(未完待续)  
 
  |