XML解析之Degister(新手必看)

XML已经成为了我们开发过程中不可缺少的技术。我们可以用它来描述程序的配置,适配不同的数据格式,甚至作为数据库使用。
帮助处理XML的工具很多,它们让我们活得更轻松。JakartaCommons下的Digester就是一个不错的工具。它提供了一种将XML与Java对象进行映射的方便方法。这么说可能让新手更迷惑,还是举个例子吧!
我们有这样一个XML文件:
  1. <!--Memos_2004-01-16.xml-->
  2. <?xmlversion="1.0"?>
  3. <memos>
  4. <memo>
  5. <title>AboutJakatarcommonsDigester</title>
  6. <date>2004-01-1602:05</date>
  7. <body>WeareworkingonDigester1.6-dev.Becauseitsupportedread
  8. attributesofelement.Weshouldpayattentiontothereleasingof
  9. Digesterforitschanging.</body>
  10. </memo>
  11. <memo>
  12. <title>Ahha!Itsgoodnight!</title>
  13. <date>2004-01-164:19</date>
  14. <body>Ihasenhancedthebasicframeworkofmyappwithimproved
  15. architectureandperformance.Itstimetosleep.Goodnight,
  16. boys.</body>
  17. </memo>
  18. </memos>

这是我的备忘录,我用xml作为数据库。现在我们想用Java程序来读/写这个数据库应该怎么做呢?啊!对了,SAX、DOM……,好了,忘了它们吧!我们有更Easy的办法!
我们先来创建一个Memo类,它用来保存一条Memo。它有三个属性用来保存标题、日期以及Memo的正文。我们提供了公共的Setter和Getter,并且我们重载了toString()方法以便查看运行结果。
  1. /*Memo.java*/
  2. packagekitta.memo;
  3. publicclassMemo
  4. {
  5. /*-----/InstanceField(s)/------------------------------------------------*/
  6. privateString_title;
  7. privateString_body;
  8. privateString_date;
  9. /*-----/Constructor(s)/---------------------------------------------------*/
  10. publicMemo()
  11. {
  12. /*donothingnow*/
  13. }
  14. /*-----/Getter(s)&Setter(s)/--------------------------------------------*/
  15. publicStringgetBody()
  16. {
  17. return_body;
  18. }
  19. publicvoidsetBody(Stringbody)
  20. {
  21. _body=body;
  22. }
  23. publicStringgetTitle()
  24. {
  25. return_title;
  26. }
  27. publicvoidsetTitle(Stringtitle)
  28. {
  29. _title=title;
  30. }
  31. publicStringgetDate()
  32. {
  33. return_date;
  34. }
  35. publicvoidsetDate(Stringdate)
  36. {
  37. _date=date;
  38. }
  39. /*-----/OverridedMethod(s)/----------------------------------------------*/
  40. publicStringtoString()
  41. {
  42. StringBufferbuf=newStringBuffer();
  43. buf.append("\t").append(_title);
  44. buf.append("\tat\t").append(_date).append("\n\n");
  45. buf.append("\t").append(_body).append("\n");
  46. buf.append("-----------------------------------------------------------\n");
  47. returnbuf.toString();
  48. }
  49. }



然后是Memos类,它实际上是一个Memo对象的集合,完全可以用一个Collection的子类去代替它,但是这里之所以还是使用它主要是为了概念上的清晰。它同样很简单,一个私有属性_memos用来保存所有Memo对象的实例,一个共有方法addMemo()用来添加Memo,toString()方法的目的同上。
  1. /*Memos.java*/
  2. packagekitta.memo;
  3. importjava.util.Collection;
  4. importjava.util.Iterator;
  5. importjava.util.Vector;
  6. publicclassMemos
  7. {
  8. /*-----/InstanceFields/--------------------------------------------------*/
  9. privateCollection_memos=newVector();
  10. /*-----/Constructor(s)/---------------------------------------------------*/
  11. publicMemos()
  12. {
  13. /*donothing*/
  14. }
  15. /*-----/Getter(s)&Setter(s)/--------------------------------------------*/
  16. publicvoidaddMemo(Memomemo)
  17. {
  18. _memos.add(memo);
  19. }
  20. /*-----/OverridedMethod(s)/----------------------------------------------*/
  21. publicStringtoString()
  22. {
  23. StringBufferbuf=newStringBuffer();
  24. buf.append("-----------------------------------------------------------\n");
  25. buf.append("MemoApplication\n");
  26. buf.append("(").append(_memos.size()).append("memostotalfound.)\n");
  27. buf.append("-----------------------------------------------------------\n");
  28. for(Iteratoritr=_memos.iterator();itr.hasNext();)
  29. {
  30. Memom=(Memo)itr.next();
  31. buf.append(m.toString());
  32. }
  33. returnbuf.toString();
  34. }
  35. }



请注意init方法,它告诉Digester如何将XML中的数据映射到我们的Java对象。
  1. packagekitta.memo;
  2. importjava.io.IOException;
  3. importjava.io.InputStream;
  4. importorg.apache.commons.digester.Digester;
  5. publicclassMemoApp
  6. {
  7. /*-----/InstanceField(s)/------------------------------------------------*/
  8. privateMemos_memos;
  9. /*-----/Constructor(s)/---------------------------------------------------*/
  10. publicMemoApp()
  11. {
  12. /*donothing*/
  13. }
  14. /*-----/PrivateMethods(s)/-----------------------------------------------*/
  15. /**
  16. *InitializestheinstanceofDigester.
  17. */
  18. privatevoidinit(Digesterdgstr)
  19. {
  20. /*当遇到memos元素时创建一个Memos对象*/
  21. dgstr.addObjectCreate("memos",Memos.class);
  22. /*当遇到memo元素时创建一个Memo对象*/
  23. dgstr.addObjectCreate("memos/memo",Memo.class);
  24. /*当遇到memos/memo/title元素时,调用当前Memo对象的setTitle方法*/
  25. dgstr.addBeanPropertySetter("memos/memo/title","title");
  26. /*当遇到memos/memo/body元素时,调用当前Memo对象的setBody*/
  27. dgstr.addBeanPropertySetter("memos/memo/body","body");
  28. /*当遇到memos/memo/date元素时,调用当前Memo对象的setDate方法*/
  29. dgstr.addBeanPropertySetter("memos/memo/date","date");
  30. /*调用当前的Memos对象的addMemo方法,参数为当前的Memo对象*/
  31. dgstr.addSetNext("memos/memo","addMemo");
  32. }
  33. /**
  34. *printsdetailsofmemostostandardout.
  35. */
  36. privatevoidprint()
  37. {
  38. System.out.println(_memos);
  39. }
  40. /**
  41. *mapsthexmldatatojavaobject
  42. */
  43. privatevoidload(InputStreamin)throwsException
  44. {
  45. Digesterdgstr=newDigester();
  46. init(dgstr);
  47. try
  48. {
  49. _memos=(Memos)dgstr.parse(in);
  50. }catch(IOExceptione)
  51. {
  52. thrownewException("ErroroccuredWhenloadingdata",e);
  53. }
  54. }
  55. /*-----/MainMethod/------------------------------------------------------*/
  56. publicstaticvoidmain(String[]args)throwsException
  57. {
  58. MemoAppmapp=newMemoApp();
  59. /*loadxmlfilefromclasspath*/
  60. mapp.load(MemoApp.class.getResourceAsStream("/kitta/memo/memo.xml"));
  61. mapp.print();
  62. }
  63. }



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:[email protected]:/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吗!要更好的应用,就要更深入的研究。

你可能感兴趣的:(apache,xml,IBM,Lucene,cvs)