Posted on 2006-07-18 12:20
Earth 閱讀(345)
評(píng)論(0) 編輯 收藏 所屬分類(lèi):
Java
這里是在Eclipse下的展開(kāi)圖:
?
下載源代碼
download
今天初學(xué)了一下Digester,并把它在Eclipse下跑了一遍,呵呵。學(xué)會(huì)開(kāi)始用ant來(lái)構(gòu)建任務(wù)了。發(fā)現(xiàn)如同JBuilder一樣也可以直接在TestDigester上使用Alt+Shift+X來(lái)運(yùn)行main函數(shù),不錯(cuò)。
網(wǎng)上的例子只有一個(gè)大致的皮毛,我把這個(gè)foo ,bar的例子實(shí)際實(shí)現(xiàn)了一遍(后來(lái)發(fā)現(xiàn)Digester src包中給我們提供了幾個(gè)更好的例子,不錯(cuò))。使用Digester的步驟大致如下:
????????
//
首先要new一個(gè)Digester對(duì)象
????????Digester?digester?
=
?
new
?Digester();
????????
????????
//
?不進(jìn)行XML與相應(yīng)的DTD的合法性驗(yàn)證
????????digester.setValidating(
false
);
????????
????????
//
?當(dāng)遇到<foo>時(shí)創(chuàng)建一個(gè)test.Foo對(duì)象,并將其放在棧頂
????????digester.addObjectCreate(
"
foo
"
,?
"
test.Foo
"
);
????????
????????
//
?根據(jù)<foo>元素的屬性(這里是name),對(duì)剛創(chuàng)建的Foo對(duì)象的屬性(這里也是name)進(jìn)行設(shè)置
????????
//
?注:xml中的屬性稱(chēng)為attribute,對(duì)象中的屬性稱(chēng)為property
????????digester.addSetProperties(
"
foo
"
);

????????
//
當(dāng)遇到<foo>的子元素<bar>時(shí)創(chuàng)建一個(gè)test.Bar對(duì)象,并將其放在棧頂。
????????digester.addObjectCreate(
"
foo/bar
"
,?
"
test.Bar
"
);
????????
????????
//
根據(jù)<bar>元素的屬性,對(duì)剛創(chuàng)建的Bar對(duì)象的屬性進(jìn)行設(shè)置,這里有兩個(gè):分別是id和title
????????digester.addSetProperties(
"
foo/bar
"
);
????????
????????
//
當(dāng)再次遇到<foo>的子元素<bar>時(shí)創(chuàng)建一個(gè)test.Bar對(duì)象,并將其放在棧頂,同時(shí)調(diào)用第二棧頂元素(Foo對(duì)象)的addBar方法。?
????????digester.addSetNext(
"
foo/bar
"
,?
"
addBar
"
,?
"
test.Bar
"
);

????????ClassLoader?classLoader?
=
?Thread.currentThread()
????????????????.getContextClassLoader();
????????InputStream?in?
=
?classLoader.getResourceAsStream(
"
Foobar.xml
"
);
????????Foo?foo?
=
?
null
;

????????
try
?
{

????????????
if
?(in?
!=
?
null
)?
{
????????????????foo?
=
?(Foo)?digester.parse(in);
//
分析結(jié)束后,返回根元素。
????????????}
????????}
?
catch
?(IOException?e)?
{
????????????e.printStackTrace();

????????}
?
catch
?(SAXException?e)?
{
????????????e.printStackTrace();
????????}
元素匹配模式
Digester能自動(dòng)遍歷目標(biāo)XML文檔的元素形成的層次結(jié)構(gòu),這個(gè)過(guò)程無(wú)須程序員參與。程序員的任務(wù)是,決定在解析的過(guò)程中,當(dāng)由嵌套的元素形成的一個(gè)特定序列被識(shí)別出時(shí)如何進(jìn)行處理。用以描述這種序列的機(jī)制,這就叫元素匹配模式。
當(dāng)檢索的元素序列滿足某個(gè)匹配模式時(shí),與該模式相對(duì)應(yīng)的行為就會(huì)被自動(dòng)執(zhí)行。
對(duì)于元素模式,具體來(lái)說(shuō),就是元素和子元素間,通過(guò)“/”分隔并連接在一起,對(duì)于根元素之前則無(wú)需使用“/”。例如:
<a> -- 匹配模板 "a"
<b> -- 匹配模板 "a/b"
<c/> -- 匹配模板 "a/b/c"
<c/> -- 匹配模板 "a/b/c"
</b>
<b> -- 匹配模板 "a/b"
<c/> -- 匹配模板 "a/b/c"
<c/> -- 匹配模板 "a/b/c"
<c/> -- 匹配模板 "a/b/c"
</b>
</a>
字符”*”表示任意級(jí)別,如”*/a”表示任意級(jí)別的<a>都可匹配(不包括根元素級(jí)的).
處理規(guī)則
元素匹配模式用于確定什么時(shí)候進(jìn)行處理,而處理規(guī)則則用于定義處理的內(nèi)容,也就是進(jìn)行什么樣的行動(dòng)。
Digester定義了一系列的常用的處理規(guī)則。在設(shè)置Digester時(shí),可能通過(guò)調(diào)用addRule()方法來(lái)注冊(cè)一個(gè)特定的元素匹配模式以及一個(gè)相應(yīng)的處理規(guī)則類(lèi)的實(shí)例。
用戶也可以自定義一些自己的處理規(guī)則類(lèi),用于滿足不同類(lèi)型的特殊需求。定義一個(gè)處理規(guī)則首先要擴(kuò)展org.apache.commons.digester.Rule類(lèi)。然后再根據(jù)特殊的要求來(lái)實(shí)現(xiàn)begin(), body(), end(), finish()事件處理方法。
對(duì)于一些標(biāo)準(zhǔn)的規(guī)則類(lèi),可以創(chuàng)建它們的實(shí)例,并調(diào)用digester.addRule來(lái)注冊(cè)它們。由于經(jīng)常使用它們,所以digester定義了一些簡(jiǎn)便的方法來(lái)注冊(cè)它們。如:
Rule rule = new SetNextRule(digester, "addChild","com.mycompany.mypackage.MyChildClass");
digester.addRule("a/b/c", rule);
可以用下列代碼替換
digester.addSetNext("a/b/c", "addChild", "com.mycompany.mypackage.MyChildClass");
在前面的foo, bar例子中,從log4j打印出的信息可以窺見(jiàn)它所用到的處理規(guī)則
? New match='foo'
[ObjectCreateRule]{foo}New test.Foo
[SetPropertiesRule]{foo} Setting property 'name' to 'The Parent'
? New match='foo/bar'
[ObjectCreateRule]{foo/bar}New test.Bar
[SetPropertiesRule]{foo/bar} Setting property 'id' to '123'
[SetPropertiesRule]{foo/bar} Setting property 'title' to 'The First Child'
[SetNextRule]{foo/bar} Call test.Foo.addBar(test.Bar@30c221[id=123,title=The First Child])