XML已经成为了我们开发过程中不可缺少的技术。我们可以用它来描述程序的配置,适配不同的数据格式,甚至作为数据库使用。
帮助处理XML的工具很多,它们让我们活得更轻松。JakartaCommons下的Digester就是一个不错的工具。它提供了一种将XML与Java对象进行映射的方便方法。这么说可能让新手更迷惑,还是举个例子吧!
我们有这样一个XML文件:
这是我的备忘录,我用xml作为数据库。现在我们想用Java程序来读/写这个数据库应该怎么做呢?啊!对了,SAX、DOM……,好了,忘了它们吧!我们有更Easy的办法!
我们先来创建一个Memo类,它用来保存一条Memo。它有三个属性用来保存标题、日期以及Memo的正文。我们提供了公共的Setter和Getter,并且我们重载了toString()方法以便查看运行结果。
然后是Memos类,它实际上是一个Memo对象的集合,完全可以用一个Collection的子类去代替它,但是这里之所以还是使用它主要是为了概念上的清晰。它同样很简单,一个私有属性_memos用来保存所有Memo对象的实例,一个共有方法addMemo()用来添加Memo,toString()方法的目的同上。
请注意init方法,它告诉Digester如何将XML中的数据映射到我们的Java对象。
Digester用"elem/elem/elem"的方式来匹配xml中的元素。这非常直观,实际上我们很早就开始使用类似的方式了。Digester将其称为Pattern。
Digester中还有一个重要的概念就是Rule。我们在init方法中所做的就是将Pattern和Rule关联起来。当Digester发现与我们所注册的Pattern匹配的xml元素时,就会调用我们注册时指定Rule来处理这个元素。
以上代码的测试环境为WindowsXP、JDK1.4.203、Digester1.5Release。
Degister官方资源
Website:http://jakarta.apache.org/commons/digester/index.html
CVSconnection:scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-commons/digester/
CVSWebView: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,毕竟这只是一个GettingStart吗!要更好的应用,就要更深入的研究。
帮助处理XML的工具很多,它们让我们活得更轻松。JakartaCommons下的Digester就是一个不错的工具。它提供了一种将XML与Java对象进行映射的方便方法。这么说可能让新手更迷惑,还是举个例子吧!
我们有这样一个XML文件:
- <!--Memos_2004-01-16.xml-->
- <?xmlversion="1.0"?>
- <memos>
- <memo>
- <title>AboutJakatarcommonsDigester</title>
- <date>2004-01-1602:05</date>
- <body>WeareworkingonDigester1.6-dev.Becauseitsupportedread
- attributesofelement.Weshouldpayattentiontothereleasingof
- Digesterforitschanging.</body>
- </memo>
- <memo>
- <title>Ahha!Itsgoodnight!</title>
- <date>2004-01-164:19</date>
- <body>Ihasenhancedthebasicframeworkofmyappwithimproved
- architectureandperformance.Itstimetosleep.Goodnight,
- boys.</body>
- </memo>
- </memos>
这是我的备忘录,我用xml作为数据库。现在我们想用Java程序来读/写这个数据库应该怎么做呢?啊!对了,SAX、DOM……,好了,忘了它们吧!我们有更Easy的办法!
我们先来创建一个Memo类,它用来保存一条Memo。它有三个属性用来保存标题、日期以及Memo的正文。我们提供了公共的Setter和Getter,并且我们重载了toString()方法以便查看运行结果。
- /*Memo.java*/
- packagekitta.memo;
- publicclassMemo
- {
- /*-----/InstanceField(s)/------------------------------------------------*/
- privateString_title;
- privateString_body;
- privateString_date;
- /*-----/Constructor(s)/---------------------------------------------------*/
- publicMemo()
- {
- /*donothingnow*/
- }
- /*-----/Getter(s)&Setter(s)/--------------------------------------------*/
- publicStringgetBody()
- {
- return_body;
- }
- publicvoidsetBody(Stringbody)
- {
- _body=body;
- }
- publicStringgetTitle()
- {
- return_title;
- }
- publicvoidsetTitle(Stringtitle)
- {
- _title=title;
- }
- publicStringgetDate()
- {
- return_date;
- }
- publicvoidsetDate(Stringdate)
- {
- _date=date;
- }
- /*-----/OverridedMethod(s)/----------------------------------------------*/
- publicStringtoString()
- {
- StringBufferbuf=newStringBuffer();
- buf.append("\t").append(_title);
- buf.append("\tat\t").append(_date).append("\n\n");
- buf.append("\t").append(_body).append("\n");
- buf.append("-----------------------------------------------------------\n");
- returnbuf.toString();
- }
- }
然后是Memos类,它实际上是一个Memo对象的集合,完全可以用一个Collection的子类去代替它,但是这里之所以还是使用它主要是为了概念上的清晰。它同样很简单,一个私有属性_memos用来保存所有Memo对象的实例,一个共有方法addMemo()用来添加Memo,toString()方法的目的同上。
- /*Memos.java*/
- packagekitta.memo;
- importjava.util.Collection;
- importjava.util.Iterator;
- importjava.util.Vector;
- publicclassMemos
- {
- /*-----/InstanceFields/--------------------------------------------------*/
- privateCollection_memos=newVector();
- /*-----/Constructor(s)/---------------------------------------------------*/
- publicMemos()
- {
- /*donothing*/
- }
- /*-----/Getter(s)&Setter(s)/--------------------------------------------*/
- publicvoidaddMemo(Memomemo)
- {
- _memos.add(memo);
- }
- /*-----/OverridedMethod(s)/----------------------------------------------*/
- publicStringtoString()
- {
- StringBufferbuf=newStringBuffer();
- buf.append("-----------------------------------------------------------\n");
- buf.append("MemoApplication\n");
- buf.append("(").append(_memos.size()).append("memostotalfound.)\n");
- buf.append("-----------------------------------------------------------\n");
- for(Iteratoritr=_memos.iterator();itr.hasNext();)
- {
- Memom=(Memo)itr.next();
- buf.append(m.toString());
- }
- returnbuf.toString();
- }
- }
请注意init方法,它告诉Digester如何将XML中的数据映射到我们的Java对象。
- packagekitta.memo;
- importjava.io.IOException;
- importjava.io.InputStream;
- importorg.apache.commons.digester.Digester;
- publicclassMemoApp
- {
- /*-----/InstanceField(s)/------------------------------------------------*/
- privateMemos_memos;
- /*-----/Constructor(s)/---------------------------------------------------*/
- publicMemoApp()
- {
- /*donothing*/
- }
- /*-----/PrivateMethods(s)/-----------------------------------------------*/
- /**
- *InitializestheinstanceofDigester.
- */
- privatevoidinit(Digesterdgstr)
- {
- /*当遇到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");
- }
- /**
- *printsdetailsofmemostostandardout.
- */
- privatevoidprint()
- {
- System.out.println(_memos);
- }
- /**
- *mapsthexmldatatojavaobject
- */
- privatevoidload(InputStreamin)throwsException
- {
- Digesterdgstr=newDigester();
- init(dgstr);
- try
- {
- _memos=(Memos)dgstr.parse(in);
- }catch(IOExceptione)
- {
- thrownewException("ErroroccuredWhenloadingdata",e);
- }
- }
- /*-----/MainMethod/------------------------------------------------------*/
- publicstaticvoidmain(String[]args)throwsException
- {
- MemoAppmapp=newMemoApp();
- /*loadxmlfilefromclasspath*/
- mapp.load(MemoApp.class.getResourceAsStream("/kitta/memo/memo.xml"));
- mapp.print();
- }
- }
Digester用"elem/elem/elem"的方式来匹配xml中的元素。这非常直观,实际上我们很早就开始使用类似的方式了。Digester将其称为Pattern。
Digester中还有一个重要的概念就是Rule。我们在init方法中所做的就是将Pattern和Rule关联起来。当Digester发现与我们所注册的Pattern匹配的xml元素时,就会调用我们注册时指定Rule来处理这个元素。
环境
以上代码的测试环境为WindowsXP、JDK1.4.203、Digester1.5Release。
相关资源
Degister官方资源
Website:http://jakarta.apache.org/commons/digester/index.html
CVSconnection:scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-commons/digester/
CVSWebView: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,毕竟这只是一个GettingStart吗!要更好的应用,就要更深入的研究。