XML解析之Degister(新手必看)

XML已经成为了我们开发过程中不可缺少的技术。我们可以用它来描述程序的配置,适配不同的数据格式,甚至作为数据库使用。
帮助处理XML的工具很多,它们让我们活得更轻松。Jakarta Commons下的Digester就是一个不错的工具。它提供了一种将XML与Java对象进行映射的方便方法。这么说可能让新手更迷惑,还是举个例子吧!
我们有这样一个XML文件:
  1.  
  2. <!-- Memos_2004-01-16.xml -->
  3. <?xml version="1.0"?>
  4. <memos>
  5. <memo>
  6.     <title>About Jakatar commons Digester</title>
  7.     <date>2004-01-16 02:05</date>
  8.     <body>We are working on Digester 1.6-dev.Because it supported read
  9.          attributes of element.We should pay attention to the releasing of 
  10.          Digester for its changing.</body>
  11. </memo>
  12.  
  13. <memo>
  14.     <title>Ah ha! Its good night!</title>
  15.     <date>2004-01-16 4:19</date>
  16.     <body>I has enhanced the basic framework of my app with improved 
  17.          architecture and performance. Its time to sleep. Good night, 
  18.          boys.</body>
  19. </memo>
  20. </memos>

这是我的备忘录,我用xml作为数据库。现在我们想用Java程序来读/写这个数据库应该怎么做呢?啊!对了,SAX、DOM……,好了,忘了它们吧!我们有更Easy的办法!
我们先来创建一个Memo类,它用来保存一条Memo。它有三个属性用来保存标题、日期以及Memo的正文。我们提供了公共的Setter和Getter,并且我们重载了toString()方法以便查看运行结果。
  1.  
  2. /* Memo.java */
  3. package kitta.memo;
  4.  
  5. public class Memo
  6. {
  7.     /*-----/ Instance Field(s) /------------------------------------------------*/
  8.     private String _title;
  9.     private String _body;
  10.     private String _date;
  11.     /*-----/ Constructor(s) /---------------------------------------------------*/
  12.     public Memo()
  13.     {
  14.         /* do nothing now */
  15.     }
  16.  
  17.     /*-----/ Getter(s) & Setter(s) /--------------------------------------------*/
  18.     public String getBody()
  19.     {
  20.         return _body;
  21.     }
  22.  
  23.     public void setBody(String body)
  24.     {
  25.         _body = body;
  26.     }
  27.  
  28.     public String getTitle()
  29.     {
  30.         return _title;
  31.     }
  32.  
  33.     public void setTitle(String title)
  34.     {
  35.         _title = title;
  36.     }
  37.  
  38.     public String getDate()
  39.     {
  40.         return _date;
  41.     }
  42.     public void setDate(String date)
  43.     {
  44.         _date = date;
  45.     }
  46.   /*-----/ Overrided Method(s) /----------------------------------------------*/
  47.     public String toString()
  48.     {
  49.         StringBuffer buf = new StringBuffer();
  50.         buf.append("/t").append(_title);
  51.         buf.append("/tat/t").append(_date).append("/n/n");
  52.         buf.append("/t").append(_body).append("/n");
  53.         buf.append("-----------------------------------------------------------/n");
  54.         return buf.toString();
  55.     }
  56. }



然后是Memos类,它实际上是一个Memo对象的集合,完全可以用一个Collection的子类去代替它,但是这里之所以还是使用它主要是为了概念上的清晰。它同样很简单,一个私有属性_memos用来保存所有Memo对象的实例,一个共有方法addMemo()用来添加Memo,toString()方法的目的同上。
  1.  
  2. /* Memos.java */
  3. package kitta.memo;
  4.  
  5. import java.util.Collection;
  6. import java.util.Iterator;
  7. import java.util.Vector;
  8.  
  9.  
  10. public class Memos
  11. {
  12.   /*-----/ Instance Fields /--------------------------------------------------*/
  13.   private Collection _memos=new Vector();
  14.   /*-----/ Constructor(s) /---------------------------------------------------*/
  15.   public Memos()
  16.   {
  17.     /* do nothing */
  18.   }
  19.   /*-----/ Getter(s) & Setter(s) /--------------------------------------------*/
  20.   public void addMemo(Memo memo)
  21.   {
  22.     _memos.add(memo);
  23.   }
  24.   /*-----/ Overrided Method(s) /----------------------------------------------*/
  25.   public String toString()
  26.   {
  27.     StringBuffer buf = new StringBuffer();
  28.     buf.append("-----------------------------------------------------------/n");
  29.     buf.append("        Memo Application/n");
  30.     buf.append("    (").append(_memos.size()).append(" memos total found.)/n");
  31.     buf.append("-----------------------------------------------------------/n");
  32.   
  33.     for(Iterator itr = _memos.iterator();itr.hasNext();)
  34.     {
  35.       Memo m = (Memo) itr.next();
  36.       buf.append(m.toString());
  37.     }
  38.         return buf.toString();
  39.   }
  40. }



请注意init方法,它告诉Digester如何将XML中的数据映射到我们的Java对象。
  1.  
  2. package kitta.memo;
  3.  
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6.  
  7. import org.apache.commons.digester.Digester;
  8.  
  9. public class MemoApp
  10. {
  11.   /*-----/ Instance Field(s) /------------------------------------------------*/
  12.   private    Memos _memos;
  13.   /*-----/ Constructor(s) /---------------------------------------------------*/
  14.     public MemoApp()
  15.     {
  16.         /* do nothing */
  17.     }
  18.   /*-----/ Private Methods(s) /-----------------------------------------------*/
  19.   /**
  20.    * Initializes the instance of Digester.
  21.    */
  22.     private void init(Digester dgstr)
  23.     {
  24.     /* 当遇到memos元素时创建一个Memos对象 */
  25.     dgstr.addObjectCreate("memos", Memos.class);
  26.     /* 当遇到memo元素时创建一个Memo对象 */
  27.     dgstr.addObjectCreate("memos/memo", Memo.class);
  28.     /* 当遇到memos/memo/title元素时,调用当前Memo对象的setTitle方法 */
  29.     dgstr.addBeanPropertySetter("memos/memo/title""title");
  30.     /* 当遇到memos/memo/body元素时,调用当前Memo对象的setBody */
  31.     dgstr.addBeanPropertySetter("memos/memo/body""body");
  32.     /* 当遇到memos/memo/date元素时,调用当前Memo对象的setDate方法 */
  33.     dgstr.addBeanPropertySetter("memos/memo/date""date");
  34.     /* 调用当前的Memos对象的addMemo方法,参数为当前的Memo对象 */
  35.     dgstr.addSetNext("memos/memo""addMemo");
  36.    
  37.     }
  38.   /**
  39.    * prints details of memos to standard out.
  40.    */
  41.   private void print()
  42.   {
  43.     System.out.println(_memos);
  44.   }
  45.   /**
  46.    * maps the xml data to java object
  47.    */  
  48.   private void load(InputStream in) throws Exception
  49.     {
  50.         Digester dgstr = new Digester();
  51.     init(dgstr);
  52.         try
  53.         {
  54.             _memos = (Memos) dgstr.parse(in);
  55.         } catch (IOException e)
  56.         {
  57.       throw new Exception("Error occured When loading data",e);
  58.         }
  59.     }
  60.   /*-----/ Main Method /------------------------------------------------------*/
  61.   public static void main(String[] args) throws Exception
  62.     {
  63.         MemoApp mapp = new MemoApp();
  64.     /* load xml file from classpath */
  65.     mapp.load(MemoApp.class.getResourceAsStream("/kitta/memo/memo.xml"));
  66.     mapp.print();
  67.     }
  68. }



Digester用"elem/elem/elem"的方式来匹配xml中的元素。这非常直观,实际上我们很早就开始使用类似的方式了。Digester将其称为Pattern。
Digester中还有一个重要的概念就是Rule。我们在init方法中所做的就是将Pattern和Rule关联起来。当Digester发现与我们所注册的Pattern匹配的xml元素时,就会调用我们注册时指定Rule来处理这个元素。

环境


以上代码的测试环境为Windows XP、JDK 1.4.2 03、Digester 1.5 Release。

相关资源


Degister官方资源
Web site: http://jakarta.apache.org/commons/digester/index.html
CVS connection: scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-commons/digester/
CVS Web View: http://cvs.apache.org/viewcvs/jakarta-commons/digester/

一些其它地方的文章:
http://www-106.ibm.com/developerworks/java/library/j-lucene/
http://www.javaworld.com/javaworld/jw-10-2002/jw-1025-opensourceprofile.html
http://www.onjava.com/pub/a/onjava/2002/10/23/digester.html

最后


好啦!就这么简单!因为这只是一些基本的应用,它可以帮助你了解Digester,毕竟这只是一个Getting Start吗!要更好的应用,就要更深入的研究。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值