Getting Start: Apache jakarta commons Digester 
kitta 原创  (参与分:7570,专家分:500)   发表:2004-1-17 上午1:02   更新:2004-1-24 下午10:16   版本:1.0   阅读:991次 
 XML已经成为了我们开发过程中不可缺少的技术。我们可以用它来描述程序的配置,适配不同的数据格式,甚至作为数据库使用。
帮助处理XML的工具很多,它们让我们活得更轻松。Jakarta Commons下的Digester就是一个不错的工具。它提供了一种将XML与Java对象进行映射的方便方法。这么说可能让新手更迷惑,还是举个例子吧!
我们有这样一个XML文件:<!-- Memos_2004-01-16.xml --><?xml version="1.0"?><memos><memo> <title>About Jakatar commons Digester</title> <date>2004-01-16 02:05</date> <body>We are working on Digester 1.6-dev.Because it supported read         attributes of element.We should pay attention to the releasing of          Digester for its changing.</body></memo><memo> <title>Ah ha! It's good night!</title> <date>2004-01-16 4:19</date> <body>I has enhanced the basic framework of my app with improved          architecture and performance. It's time to sleep. Good night,          boys.</body></memo></memos>这是我的备忘录,我用xml作为“数据库”。现在我们想用Java程序来读/写这个“数据库”应该怎么做呢?啊!对了,SAX、DOM……,好了,忘了它们吧!我们有更Easy的办法!
我们先来创建一个Memo类,它用来保存一条Memo。它有三个属性用来保存标题、日期以及Memo的正文。我们提供了公共的Setter和Getter,并且我们重载了toString()方法以便查看运行结果。/* Memo.java */package kitta.memo;public class Memo{ /*-----/ Instance Field(s) /------------------------------------------------*/ private String _title; private String _body; private String _date; /*-----/ Constructor(s) /---------------------------------------------------*/ public Memo() { /* do nothing now */ } /*-----/ Getter(s) & Setter(s) /--------------------------------------------*/ public String getBody() { return _body; } public void setBody(String body) { _body = body; } public String getTitle() { return _title; } public void setTitle(String title) { _title = title; } public String getDate() { return _date; } public void setDate(String date) { _date = date; }  /*-----/ Overrided Method(s) /----------------------------------------------*/ public String toString() { StringBuffer buf = new StringBuffer(); buf.append("\t").append(_title); buf.append("\tat\t").append(_date).append("\n\n"); buf.append("\t").append(_body).append("\n"); buf.append("-----------------------------------------------------------\n"); return buf.toString(); }}然后是Memos类,它实际上是一个Memo对象的集合,完全可以用一个Collection的子类去代替它,但是这里之所以还是使用它主要是为了概念上的清晰。它同样很简单,一个私有属性_memos用来保存所有Memo对象的实例,一个共有方法addMemo()用来添加Memo,toString()方法的目的同上。/* Memos.java */package kitta.memo;import java.util.Collection;import java.util.Iterator;import java.util.Vector;public class Memos{  /*-----/ Instance Fields /--------------------------------------------------*/  private Collection _memos=new Vector();  /*-----/ Constructor(s) /---------------------------------------------------*/  public Memos()  {    /* do nothing */  }  /*-----/ Getter(s) & Setter(s) /--------------------------------------------*/  public void addMemo(Memo memo)  {    _memos.add(memo);  }  /*-----/ Overrided Method(s) /----------------------------------------------*/  public String toString()  {    StringBuffer buf = new StringBuffer();    buf.append("-----------------------------------------------------------\n");    buf.append("        Memo Application\n");    buf.append("    (").append(_memos.size()).append(" memos total found.)\n");    buf.append("-----------------------------------------------------------\n");      for(Iterator itr = _memos.iterator();itr.hasNext();)    {      Memo m = (Memo) itr.next();      buf.append(m.toString());    } return buf.toString();  }}请注意init方法,它告诉Digester如何将XML中的数据映射到我们的Java对象。package kitta.memo;import java.io.IOException;import java.io.InputStream;import org.apache.commons.digester.Digester;public class MemoApp{  /*-----/ Instance Field(s) /------------------------------------------------*/  private Memos _memos;  /*-----/ Constructor(s) /---------------------------------------------------*/ public MemoApp() { /* do nothing */ }  /*-----/ Private Methods(s) /-----------------------------------------------*/  /**   * Initializes the instance of Digester.   */ private void init(Digester dgstr) {    /* 当遇到memos元素时创建一个Memos对象 */    dgstr.addObjectCreate("memos", Memos.class);    /* 当遇到memo元素时创建一个Memo对象 */    dgstr.addObjectCreate("memos/memo", Memo.class);    /* 当遇到memos/memo/title元素时,调用当前Memo对象的setTitle方法 */    dgstr.addBeanPropertySetter("memos/memo/title", "title");    /* 当遇到memos/memo/body元素时,调用当前Memo对象的setBody */    dgstr.addBeanPropertySetter("memos/memo/body", "body");    /* 当遇到memos/memo/date元素时,调用当前Memo对象的setDate方法 */    dgstr.addBeanPropertySetter("memos/memo/date", "date");    /* 调用当前的Memos对象的addMemo方法,参数为当前的Memo对象 */    dgstr.addSetNext("memos/memo", "addMemo");    }  /**   * prints details of memos to standard out.   */  private void print()  {    System.out.println(_memos);  }  /**   * maps the xml data to java object   */    private void load(InputStream in) throws Exception { Digester dgstr = new Digester();    init(dgstr); try { _memos = (Memos) dgstr.parse(in); } catch (IOException e) {      throw new Exception("Error occured When loading data",e); } }  /*-----/ Main Method /------------------------------------------------------*/  public static void main(String[] args) throws Exception { MemoApp mapp = new MemoApp();    /* load xml file from classpath */    mapp.load(MemoApp.class.getResourceAsStream("/kitta/memo/memo.xml"));    mapp.print(); }}