一個簡單的例子
假定有兩個JavaBean如下,分別為Foo和Bar
package mypackage;
public class Foo {
public void addBar(Bar bar);
public Bar findBar(int id);
public Iterator getBars();
public String getName();
public void setName(String name);
}
public mypackage;
public class Bar {
public int getId();
public void setId(int id);
public String getTitle();
public void setTitle(String title);
}
用下面的xml文件進(jìn)行配置
<foo name="The Parent">
<bar id="123" title="The First Child"/>
<bar id="456" title="The Second Child"/>
</foo>
用下面幾行代碼即可完成配置文件解析工作:
Digest解析代碼 |
注釋 |
Digester digester = new Digester(); |
|
digester.setValidating(false); |
不進(jìn)行XML與相應(yīng)的DTD的合法性驗證 |
digester.addObjectCreate("foo", "mypackage.Foo"); |
當(dāng)遇到<foo>時創(chuàng)建一個mypackage.Foo對象,并將其放在棧頂 |
digester.addSetProperties("foo"); |
根據(jù)<foo>元素的屬性(attribute),對剛創(chuàng)建的Foo對象的屬性(property)進(jìn)行設(shè)置 |
digester.addObjectCreate("foo/bar", "mypackage.Bar"); |
當(dāng)遇到<foo>的子元素<bar>時創(chuàng)建一個mypackage.Bar對象,并將其放在棧頂。 |
digester.addSetProperties("foo/bar"); |
根據(jù)<bar>元素的屬性(attribute),對剛創(chuàng)建的Bar對象的屬性(property)進(jìn)行設(shè)置 |
digester.addSetNext("foo/bar", "addBar", "mypackage.Bar"); |
當(dāng)再次遇到<foo>的子元素<bar>時創(chuàng)建一個mypackage.Bar對象,并將其放在棧頂,同時調(diào)用第二棧頂元素(Foo對象)的addBar方法。 |
Foo foo = (Foo) digester.parse(); |
分析結(jié)束后,返回根元素。 |
基本情況
熟悉用SAX來處理XML文檔的程序員,會發(fā)現(xiàn)Digester隱藏了遍歷XML元素這些細(xì)節(jié),而是提供了更高一層的、更友好的SAX事件接口,從而讓程序員的精力放在對數(shù)據(jù)的處理過程中。
使用Digester,須按照以下步驟:
- 創(chuàng)建一個org.apache.commons.digester.Digester實(shí)例。一個解析請求完成后,這個Digester可以被后面復(fù)用。但也不要試圖在不同的線程中從共享一個Digester實(shí)例。
- 根據(jù)需要設(shè)置一些配置屬性(configuration properties),以控制下一步的解析操作。
- 將一個或幾個初始對象(initial object)壓入Digester對象棧,本步驟不是必須的。
- 注冊所有的元素匹配模板(elemet matching pattern)。當(dāng)一個模板被從輸入文檔中識別出來以后,與其相聯(lián)系的處理規(guī)則(processing rules)被激活。對一個特定的模板,可以定義任意多的規(guī)則,當(dāng)識別出該模板后,這些規(guī)則依序依次執(zhí)行。
- 調(diào)用digester.parse()方法,一個XML文檔的引用(用多種方式供選擇)要傳給這個方法。注意,需要捕捉并處理IOException或SAXEception或處理過程中拋出的異常。
元素匹配模板
Digester能自動遍歷目標(biāo)XML文檔的元素形成的層次結(jié)構(gòu),這個過程無需程序員參與。程序員的任務(wù)是決定,在解析的過程中,當(dāng)由嵌套的元素形成的一個特定序列被識別出時,如何處理它。用以描述這種序列的機(jī)制,就叫“元素匹配模板”。
具體說來,元素和其子元素間,用”/”相隔,如果一些元素前沒有”/”則其必為根元素。如例:
<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>
字符”*”表示任意級別,如”*/a”表示任意級別的<a>都可匹配(不包括根元素級的).熟悉XLST的朋友,對這種思路一定不陌生。
從上面的描述,可知某個元素同時滿足多個匹配模板是非常可能的,在這種情況下,與各個模板相關(guān)聯(lián)的處理規(guī)則(processing rule)的執(zhí)行順序如下:對begin或body方法,按照各個rule的注冊順序的先后,對end方法則是注冊順序的反序。
處理規(guī)則(processing rule)
元素匹配模板用以識別什么時候采取行動,處理規(guī)則則用以定義行動的內(nèi)容。
從形式上講,一個處理規(guī)則是一個java類,它擴(kuò)展了org.apache.commons.digester.Rule類。每個處理規(guī)則,實(shí)現(xiàn)下列的 一個或幾個事件處理方法(event method),當(dāng)相應(yīng)的模板匹配成功以后,在已定義的某個時刻,這些事件方法會被觸發(fā)。
- begin(),在一個匹配元素被識別出后的“開始”時刻被調(diào)用,這個元素的所有屬性放在一個數(shù)據(jù)結(jié)構(gòu)中被傳遞給begin()
- body(),當(dāng)元素的嵌套內(nèi)容(如子元素)被識別出時被調(diào)用。在解析的過程中,前后的空白被去掉了
- end(),匹配元素的“結(jié)束”時刻被調(diào)用。如果子元素也匹配相關(guān)的規(guī)則,則這些規(guī)則的方法需都執(zhí)行畢,才能達(dá)到該元素的“結(jié)束”時刻。
- finish(),解析結(jié)束時被調(diào)用,以提供給各個規(guī)則以清理臨時數(shù)據(jù)的機(jī)會。
在設(shè)置digester時,通過調(diào)用addRule()方法,來注冊一個特定的元素匹配模板以及相應(yīng)的一個Rule類的實(shí)例。如上所述,Rule類中的事件處理方法,會在適當(dāng)?shù)臅r間被調(diào)用。這個機(jī)制,允許動態(tài)地生成Rule的實(shí)現(xiàn)。
另外,digester也提供了一些處理常見情況的處理規(guī)則類。
- ObjectCreateRule, 當(dāng)begin()方法被調(diào)用時,這個規(guī)則類實(shí)例化一個指定的java類,并將其壓入棧頂。這個被實(shí)例化的類的名字,默認(rèn)是這個規(guī)則類構(gòu)造函數(shù)得到的參數(shù), 也可以通過指定正在處理的xml元素的屬性來傳遞一個新的類的名字。當(dāng)end()方法被調(diào)用 時,棧頂?shù)膶ο蟊粡棾觯珼igester中對它的任何引用將 被忽略。
- FactoryCreateRule,一個非常有用的ObjectCreateRule的變體。
- SetPropertiesRule, 當(dāng)begin()方法被調(diào)用時,digester使用標(biāo)準(zhǔn)的Java Relection API來識別JavaBean的屬性設(shè)置方法(setter method),這些方法名稱中包含屬性(property)的名字,這些屬性與XML元素的屬性(attribute)匹配,于是這些方法被調(diào)用并將相 應(yīng)的屬性值(attribute value)傳給它們。這些自然的映射可以被重寫。建議不要過度使用這項功能,在大多數(shù)情況下,使用標(biāo)準(zhǔn)的BeanInfo機(jī)制會更好。
- SetPropertyRule, 當(dāng)begin()方法被調(diào)用時,digester調(diào)用棧頂對象的一個特定的屬性設(shè)置方法(property setter)并傳給它特定的值(property和值分別由兩個attribute命名)。這對XML需要遵循一個指定的DTD時比較有用,你可以設(shè)置 一個特別的屬性(property),雖然在指定DTD沒有attribute與其相對應(yīng)。
- SetNextRule, 當(dāng)end()方法被調(diào)用時,digester分析第二棧頂元素,尋找一個特定屬性(property)的設(shè)置方法(setter method),并接著調(diào)用這個方法,以棧頂?shù)脑刈鲄?shù)。這個規(guī)則通常用來在兩個對象間建立1對多的關(guān)系,所用的方法也常被叫做addChild什么 的。
- SetTopRule,當(dāng)end()方法被調(diào)用時,digester分析棧 頂元素,尋找一個特定屬性(property)的設(shè)置方法(setter method),并接著調(diào)用這個方法,以第二棧頂?shù)脑刈鲄?shù)。這個規(guī)則通常用來在兩個對象間建立1對多的關(guān)系,所用的方法也常被叫做setParent 什么的。
- CallMethodRule,這個規(guī)則設(shè)置當(dāng)end()被調(diào)用時執(zhí)行的棧頂對象的自定義方法,通過對這個規(guī)則的設(shè)置,來指定方法的名字、參數(shù)的數(shù)量以及定義的參數(shù)類型的Java類的名字。實(shí)際的參數(shù)值,來自激活這個方法的元素的子元素。
- CallParamRule,這個規(guī)則用來指定CallMethodRule的參數(shù)的值的來源,它可以來自一個特定的屬性,或子元素的body的內(nèi)容.
- NodeCreateRule,一個特殊的規(guī)則,將對象樹的一部分轉(zhuǎn)換成一個DOM結(jié)點(diǎn)(Node),并壓入棧頂。
對這些標(biāo)準(zhǔn)的規(guī)則類,可以創(chuàng)建它們的實(shí)例,并調(diào)用digester.addRule來注冊它們。由于經(jīng)常使用它們,所以digester定義了一些簡便的方法來注冊它們。如:
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");
對象棧
對digester技術(shù)最普通的應(yīng)用,是用來動態(tài)創(chuàng)建一個由Java對象構(gòu)成的樹結(jié)構(gòu),各對象的屬性以及對象間的關(guān)系,基于XML文檔的內(nèi)容來設(shè)置 (XML文檔就是一棵樹)。為實(shí)現(xiàn)這種應(yīng)用,Digester提供了一個對象棧,以供在相關(guān)的模板識別后被激活的處理規(guī)則操作。此棧的基本操作包括:
- clear(),清空棧的內(nèi)容
- peek(),返回對棧頂對象的引用
- pop(),將棧頂對象彈出并返回
- push(),將一個新的對象壓入棧頂
用棧的原因,就是當(dāng)識別出一個XML元素的“開始”時,將相關(guān)對象生成并壓入棧頂,這個對象在處理該元素的子元素的過程中一直在棧中,當(dāng)所有子元素都處理完后,解析器遇到這個元素的“結(jié)束”時,則彈出此對象,并進(jìn)行相關(guān)的處理。
如何描述對象間的關(guān)系呢?將棧頂?shù)膶ο笞鰹橐粋€參數(shù),傳遞給第二棧頂(即先于棧頂對象入棧的那個對象,在棧頂對象的下面)的一個方法,就可以簡單地建立 起一種“父子關(guān)系”,從而可以簡單地建立起1:1的關(guān)系(第二棧頂對象與棧頂對象之間)和1:N的關(guān)系(第二棧頂對象不動,N次壓棧頂彈棧頂對象).
如果取得生成的第一個對象呢?可以讓parse()方法返回,或者在調(diào)用parse()方法前,先行壓入一個對象,在parse()方法結(jié)束后彈出這個對象,則其子對象即為我們想要的第一個對象。
日志(logging)
日志是一個調(diào)試Digester規(guī)則集的非常重要的工具,它可以記錄非常豐富的信息,因它在使用Digester之前有必要了解日志是如何工作的。
Digester使用Jakarta Commons Logging,這個模塊并不是具體的日志實(shí)現(xiàn),而只是一個可設(shè)置的接口。可以設(shè)置它將各種日志信息傳遞它自身帶的基本記錄器,或者傳遞給其它的更復(fù)雜的 日志工具。具體請參考commons logging的文檔,或Jakarta Commons Logging學(xué)習(xí)筆記
Digester主要使用兩個記錄器:
- SAX相關(guān)的信息,被送往org.apache.commons.digester.Digester.sax記錄器,記錄了Digester收到的SAX的事件的信息。
- 其它的所有信息,都被送往org.apache.commons.digester.Digester記錄器,這個記錄器在調(diào)試Digester時打開而在產(chǎn)品中常將其關(guān)閉
假定用commons logging自帶的基本日志工具,并以DEBUG級別記錄Digester調(diào)試信息以及INFO級別記錄SAX事件信息,則對logging的配置文件設(shè)置如下:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester=debug org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester.sax=info
Digester包中的例子
***********Example.xml**********
<address-book>
<person id="1" category="acquaintance" try="would be ignored">
<name>Gonzo</name>
<email type="business">gonzo@muppets.com</email>
<gender result="the whole tag would be ignored">male</gender>
</person>
<person id="2" category="rolemodel">
<name>Kermit</name>
<email type="business">kermit@muppets.com</email>
<email type="home">kermie@acme.com</email>
</person>
</address-book>**********Person.java************
import java.util.HashMap;
import java.util.Iterator;
public class Person {
private int id;
private String category;
private String name;
private HashMap emails = new HashMap();
// 下面的兩個方法的名字中set以后的部分,與<person>的屬性名字對映。當(dāng)從xml文件中識別出<person>的屬性 時,如果有要求(即調(diào)用過addSetProperties方法),Digester會依據(jù)這種對映關(guān)系自動調(diào)用相應(yīng)的方法。
public void setId(int id) {
this.id = id;
}
public void setCategory(String category) {
this.category = category;
}
//對name而言,因為其值來自<name>標(biāo)簽的內(nèi)容而非屬性值,需要用addCallMethod指定識別<name>后的要調(diào)用此方法(想自動調(diào)用也要可以,需要addBeanPropertySetter,參見第下一個例子)。
public void setName(String name) {
this.name = name;
}
//同name,此時還要一一指定addEmail的參數(shù)值的來源。
public void addEmail(String type, String address) {
emails.put(type, address);
}
public void print() {
System.out.println("Person #" + id);
System.out.println(" category=" + category);
System.out.println(" name=" + name);
for(Iterator i = emails.keySet().iterator(); i.hasNext(); ) {
String type = (String) i.next();
String address = (String) emails.get(type);
System.out.println(" email (type " + type + ") : " + address);
}
}
}
**********AddressBook.java***********
import java.util.LinkedList;
import java.util.Iterator;
public class AddressBook {
LinkedList people = new LinkedList();
public void addPerson(Person p) {
people.addLast(p);
}
public void print() {
System.out.println("Address book has " + people.size() + " entries");
for(Iterator i = people.iterator(); i.hasNext(); ) {
Person p = (Person) i.next();
p.print();
}
}
}
************AddressBookDigester*********
import org.apache.commons.digester.Digester;
/**
* Usage: java Example1 example.xml
*/
public class AddressBookDigester {
public static void main(String[] args) {
if (args.length != 1) {
usage();
System.exit(-1);
}
String filename = args[0];
// 創(chuàng)建一個Digester實(shí)例
Digester d = new Digester();
// 創(chuàng)建AddressBook實(shí)例,并將其壓入棧頂。
AddressBook book = new AddressBook();
d.push(book);
// 增加規(guī)則
addRules(d);
// 處理輸入的xml文件
try {
java.io.File srcfile = new java.io.File(filename);
d.parse(srcfile);
}
catch(java.io.IOException ioe) {
System.out.println("Error reading input file:" + ioe.getMessage());
System.exit(-1);
}
catch(org.xml.sax.SAXException se) {
System.out.println("Error parsing input file:" + se.getMessage());
System.exit(-1);
}
// 將解析出的地址數(shù)據(jù)打印出來
book.print();
}
private static void addRules(Digester d) {
// 當(dāng)遇到<person>時,創(chuàng)建類Person的一個實(shí)例,并將其壓入棧頂
d.addObjectCreate("address-book/person", Person.class);
// 將<person>標(biāo)簽的屬性(attribute)與棧頂Person類對象的屬性(property)設(shè)置方法根據(jù)各自的名字進(jìn)行映射, (例如,將標(biāo)簽屬性id與屬性設(shè)置方法setId進(jìn)行映射,將標(biāo)簽屬性category與屬性設(shè)置方法setCategory進(jìn)行映射),然后將屬性的值 作參數(shù)傳遞給執(zhí)行相應(yīng)的方法。
// 如果某標(biāo)簽屬性沒法通過名字找到相應(yīng)的屬性設(shè)置方法,則此標(biāo)簽屬性被忽略(如example.xml中第一個<person>的try屬性)。
d.addSetProperties("address-book/person");
// 調(diào)用第二棧頂對象(AddressBook實(shí)例)的addPerson方法,以棧對象(Person實(shí)例)的對象為參數(shù)
d.addSetNext("address-book/person", "addPerson");
// 當(dāng)遇到<person>的子元素<name>時,調(diào)用棧頂對象(Person實(shí)例)的setName方法。
// 此處addCallMethod方法的第一參數(shù)是規(guī)則,第二個參數(shù)是方法的名字,第三個是參數(shù)的數(shù)量(為0時,表示只有一個參數(shù),且參數(shù)的值是元素的內(nèi)容)
d.addCallMethod("address-book/person/name", "setName", 0);
// 當(dāng)遇到<person>的子元素<email>時,調(diào)用棧頂對象(Person實(shí)例)的addEmail方法,addEmail 方法有兩個參數(shù),取值分別來自<email>的屬性type的值和<email>本身的內(nèi)容。
// 此處addCallParam方法的第一參數(shù)是規(guī)則,第二個參數(shù)是指明被調(diào)用方法(addEmail)參數(shù)的序號,第三個是參數(shù)為字符串時指屬性的名字)
d.addCallMethod("address-book/person/email", "addEmail", 2);
d.addCallParam("address-book/person/email", 0, "type");
d.addCallParam("address-book/person/email", 1);
}
private static void usage() {
System.out.println("Usage: java Example1 example.xml");
}
}
運(yùn)行結(jié)果如下(運(yùn)行時可能需要xml-crimson,一個源sun的XML解析器,可到http://xml.apache.org/crimson/下載)
Address book has 2 entries
Person #1
category=acquaintance
name=Gonzo
email (type business) : gonzo@muppets.com
Person #2
category=rolemodel
name=Kermit
email (type business) : kermit@muppets.com
email (type home) : kermie@acme.com
配置屬性
Digester用來解析應(yīng)用系統(tǒng)的配置文件,其本身也有很可配置的屬性。
屬性 |
描述 |
classLoader |
指 定類裝載器(class loader)。ObjectCreateRule 和 FactoryCreateRule兩個規(guī)則中,需要動態(tài)加載一些類(如那些盛放XML解析出來的數(shù)據(jù)的javaBean等),裝載器可以在次指定。如果 不指定,對這此類的加載將會利用線程上下文中的加載器(當(dāng)useContextClassLoader值為真時)或利用加載Digester的那個加載 器。 |
errorHandler |
指定 SAX ErrorHandler,以在出現(xiàn)此類錯誤時調(diào)用。默認(rèn)情況下,任何解析錯誤都會被記入日志,Digest會繼續(xù)進(jìn)行解析。 |
namespaceAware |
一個布爾值,為真時對XML文件的解析時會考慮元素的域名空間(如不同的域名空間的同名元素會視為不同的元素) |
ruleNamespaceURI |
指定后續(xù)加入的規(guī)則所屬的命名空間,如果此值為null,則加入的規(guī)則不與任何命名空間相聯(lián)系。 |
rules |
設(shè)定規(guī)則模板與XML元素的匹配處理程序。由于這個匹配程序是插件式的,所以匹配工作的完成可以用用戶定義的匹配程序未完成。默認(rèn)情況下,使用Digester提供的匹配器。 |
useContextClassLoader |
一個布爾值,為真時FactoryCreateRule 和 ObjectCreateRule 兩個規(guī)則中對類的裝載將會采用當(dāng)前線程上下文中指定的加載器。默認(rèn)情況下,對類的動態(tài)加載會利用加載Digester的那個裝載器。 |
validating |
一個布爾值,為真時解析器會根據(jù)DTD內(nèi)容對XML文檔進(jìn)行合法性檢查,默認(rèn)值是假,解析器只是檢查XML是否格式良好(well formed). |
除了上述屬性外,還可以注冊一個本地DTD,以供DOCTYPE聲明引用。這樣的注冊告訴XML解析器,當(dāng)遇到DOCTYPE聲明時,應(yīng)使用剛注冊的DTD的內(nèi)容,而不是DOCTYPE聲明中的標(biāo)識符(identifier)。
例如,Struect框架控制器中,使用下述的注冊,告訴Structs使用一個本地的DTD中的相關(guān)內(nèi)容來處理Structs配置文件,這樣可以適用 于那些沒有連接到互聯(lián)網(wǎng)的應(yīng)用環(huán)境,而在連到互聯(lián)網(wǎng)的環(huán)境中可以加快運(yùn)行速度(因為它避免了通過網(wǎng)絡(luò)去取相關(guān)的資源)。
URL url = new URL("/org/apache/struts/resources/struts-config_1_0.dtd");
digester.register("-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",url.toString());
規(guī)則集打包
通常情況下,一個規(guī)則被創(chuàng)建后,接著便注冊,然后等在event時被調(diào)用,這些規(guī)則集很難為其它應(yīng)用程序直接復(fù)用。一個解決方法是將所有規(guī)則都放在一個 類中,此由這些規(guī)則可以很簡單地被裝載然后被注冊使用。RuleSet接口就是為些而設(shè)計,一般是通過擴(kuò)展RuleSetBase類來開發(fā)規(guī)則集類。如 例:
public class MyRuleSet extends RuleSetBase {
public MyRuleSet() {
this("");
}
public MyRuleSet(String prefix) {
super();
this.prefix = prefix;
this.namespaceURI = "http://www.mycompany.com/MyNamespace";
}
protected String prefix = null;
public void addRuleInstances(Digester digester) {
digester.addObjectCreate(prefix + "foo/bar",
"com.mycompany.MyFoo");
digester.addSetProperties(prefix + "foo/bar");
}
}
可以這樣使用這個規(guī)則集
Digester digester = new Digester();
... 一些配置Digester ...
digester.addRuleSet(new MyRuleSet("baz/"));
帶命名空間的XML解析
這種情況下,使用Digester的步驟為:
- 在Digester初始化部分,指明要考慮命名空間。
digester.setNamespaceAware(true);
- 指明一些規(guī)則的命名空間,如
digester.setRuleNamespaceURI("http://www.mycompany.com/MyNamespace");
- 接下來定義一些與此命名空間有關(guān)的規(guī)則,此時可以省卻前綴,如
digester.addObjectCreate("foo/bar", "com.mycompany.MyFoo");
digester.addSetProperties("foo/bar");
- 對其它命名空間,重復(fù)前面的2步
另外,在指明要digester考慮命名空間之后,在定義匹配模板時,可以將命名空間別名加“:”作為元素名稱的一部分使用。這與無命名空間時是一致的。
開發(fā)定制的匹配處理過程
通過實(shí)現(xiàn) org.apache.commons.digester.Rules接口或擴(kuò)展org.apache.commons.digester.RulesBase類來達(dá)到定制匹配過程的目的。
Digester提供ExtendedBaseRules來擴(kuò)展了匹配模板的定義,引入了特殊通配字符?和*以及!,提供RegexRules來支持以 正則式的語法定義匹配模板,提供WithDefaultsRulesWrapper來支持默認(rèn)規(guī)則(即其它規(guī)則都不匹配時的處理規(guī)則)。
一些認(rèn)識
通過看說明材料,尤其在學(xué)習(xí)Digester包中的Catalog例子以后,有一些認(rèn)識:
1、由于xml對屬性名字的定義要求,與Java中對方法名字的定義要求不一致,導(dǎo)致出現(xiàn)不能自動映射的情況,如year-made標(biāo)簽屬性,就不可能有方法setYear-made;
2、對于根元素,與其子元素建立聯(lián)系,有幾種辦法:一種是先生成根元素實(shí)例,壓入棧,然后解析,將調(diào)用方法規(guī)則建立聯(lián)系;另一種是解析的過程中第一個創(chuàng)建它,然后用getRoot的方法得到。
3、如果某對象類構(gòu)造都要參數(shù),則此時需要擴(kuò)展AbstractObjectCreationFactory類為這種對象建立一個Factory,在這個Factory中取得初始化參數(shù)值然后再創(chuàng)建一個對象實(shí)例。
4、設(shè)有某個標(biāo)簽,要想自動用該標(biāo)簽子元素的內(nèi)容填充該標(biāo)簽對應(yīng)的對象的屬性,則需要用digester.setRules(new ExtendedBaseRules()),然后addRules(),然后再調(diào)用addBeanPropertySetter ("bala/lala/?");進(jìn)行規(guī)則定義,注意此模板中有通配符。
5、如果對象的屬性是整型,則Digester自動將xml文件中字符串值轉(zhuǎn)換為整型。
6、在指明要digester考慮命名空間之后,如果不會引起歧義,完全可以忽略命名空間的存在,除非你要針對特定的命名空間進(jìn)行特定的處理。