XML解析之Degister(新手必看)

来源:互联网 发布:英特预算软件 编辑:程序博客网 时间:2024/05/21 18:49

 导读:
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! Its 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. Its 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(
" ").append(_title); 
        buf.append(
" at ").append(_date).append(" "); 
        buf.append(
" ").append(_body).append(" "); 
        buf.append(
"----------------------------------------------------------- "); 
        
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();
        }
}
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吗!要更好的应用,就要更深入的研究。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1594162
[收藏到我的网摘] [发送Trackback] Sanshiqiduer发表于 2007年05月01日 14:38:00
        本文转自
http://blog.csdn.net/sanshiqiduer/archive/2007/05/01/1594162.aspx

原创粉丝点击