<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 20  文章 - 12  trackbacks - 0
    <2006年3月>
    2627281234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿(1)

    隨筆檔案(20)

    java論壇

    我的朋友

    最新隨筆

    搜索

    •  

    積分與排名

    • 積分 - 15080
    • 排名 - 2000

    最新評論

    閱讀排行榜

    評論排行榜

    Digester學習筆記(一)

      在windows下開發程序,用M$提供的接口處理.ini文件或管理注冊表的鍵值是非常方便的。在java平臺上開發程序,則習慣于以xml 格式的文件來存放系統的配置信息,對這種文件的解析和處理,可以用sax或dom。有沒有更簡便的方法呢?有,就是用digester模塊。
      Digester是Jakarta 子項目Commons下的一個模塊,支持基于規則的對任意XML文檔的處理。它最初是Structs項目的一部分,后因其通用性而劃歸Commons.

    下載及編譯

    cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login
    password: anoncvs
    cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout jakarta-commons/digester
    cd jakarta-commons/digester
    ant dist

      Digester的運行依賴下列包:
    1. 一個遵循Jaxp(1.1版本及以后)的XML解析器
    2. Jakarta commons beanutils包(1.5版本及以后)
    3. Jakarta commons collections包(2.1版本及以后)
    4. Jakarta commons logging包(1.0.2版本及以后)
     

    一個簡單的例子

      假定有兩個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文件進行配置
    <foo name="The Parent">
    ??<bar id="123" title="The First Child"/>
    ??<bar id="456" title="The Second Child"/>
    </foo>

      用下面幾行代碼即可完成配置文件解析工作:
    Digest解析代碼注釋
    Digesterdigester = new Digester();
    digester.setValidating(false);不進行XML與相應的DTD的合法性驗證
    digester.addObjectCreate("foo", "mypackage.Foo");當遇到<foo>時創建一個mypackage.Foo對象,并將其放在棧頂
    digester.addSetProperties("foo");根據<foo>元素的屬性(attribute),對剛創建的Foo對象的屬性(property)進行設置
    digester.addObjectCreate("foo/bar", "mypackage.Bar");當遇到<foo>的子元素<bar> 時創建一個mypackage.Bar對象,并將其放在棧頂。
    digester.addSetProperties("foo/bar");根據<bar>元素的屬性(attribute),對剛創建的Bar對象的屬性(property)進行設置
    digester.addSetNext("foo/bar", "addBar", "mypackage.Bar ");當再次遇到<foo>的子元素<bar>時創建一個mypackage.Bar對象,并將其放在棧頂,同時調用第二棧頂元素(Foo對象)的addBar方法。
    Foo foo = (Foo) digester.parse();分析結束后,返回根元素。

    基本情況

      熟悉用SAX來處理XML文檔的程序員,會發現Digester隱藏了遍歷XML元素這些細節,而是提供了更高一層的、更友好的SAX事件接口,從而讓程序員的精力放在對數據的處理過程中。
      使用Digester,須按照以下步驟:
    1. 創建一個org.apache.commons.digester.Digester實例。一個解析請求完成后,這個Digester可以被后面復用。但也不要試圖在不同的線程中從共享一個 Digester實例。
    2. 根據需要設置一些配置屬性(configuration properties),以控制下一步的解析操作。
    3. 將一個或幾個初始對象(initial object)壓入Digester對象棧,本步驟不是必須的。
    4. 注冊所有的元素匹配模板(elemet matching pattern)。當一個模板被從輸入文檔中識別出來以后,與其相聯系的處理規則(processing rules)被激活。對一個特定的模板,可以定義任意多的規則,當識別出該模板后,這些規則依序依次執行。
    5. 調用digester.parse()方法,一個XML文檔的引用(用多種方式供選擇)要傳給這個方法。注意,需要捕捉并處理IOException或SAXEception或處理過程中拋出的異常。

    元素匹配模板

      Digester能自動遍歷目標XML文檔的元素形成的層次結構,這個過程無需程序員參與。程序員的任務是決定,在解析的過程中,當由嵌套的元素形成的一個特定序列被識別出時,如何處理它。用以描述這種序列的機制,就叫"元素匹配模板"。
      具體說來,元素和其子元素間,用"/"相隔,如果一些元素前沒有"/"則其必為根元素。如例:
    <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的朋友,對這種思路一定不陌生。
      從上面的描述,可知某個元素同時滿足多個匹配模板是非常可能的,在這種情況下,與各個模板相關聯的處理規則(processing rule)的執行順序如下:對begin或body方法,按照各個rule的注冊順序的先后,對end方法則是注冊順序的反序。

    處理規則(processing rule)

      元素匹配模板用以識別什么時候采取行動,處理規則則用以定義行動的內容。
      從形式上講,一個處理規則是一個java類,它擴展了org.apache.commons.digester.Rule類。每個處理規則,實現下列的一個或幾個事件處理方法(event method),當相應的模板匹配成功以后,在已定義的某個時刻,這些事件方法會被觸發。
    1. begin(),在一個匹配元素被識別出后的"開始"時刻被調用,這個元素的所有屬性放在一個數據結構中被傳遞給begin()
    2. body(),當元素的嵌套內容(如子元素)被識別出時被調用。在解析的過程中,前后的空白被去掉了
    3. end(),匹配元素的"結束"時刻被調用。如果子元素也匹配相關的規則,則這些規則的方法需都執行畢,才能達到該元素的"結束"時刻。
    4. finish(),解析結束時被調用,以提供給各個規則以清理臨時數據的機會。

      在設置digester時,通過調用addRule()方法,來注冊一個特定的元素匹配模板以及相應的一個Rule類的實例。如上所述,Rule類中的事件處理方法,會在適當的時間被調用。這個機制,允許動態地生成Rule的實現。
      另外,digester也提供了一些處理常見情況的處理規則類。
    1. ObjectCreateRule,當begin()方法被調用時,這個規則類實例化一個指定的java類,并將其壓入棧頂。這個被實例化的類的名字,默認是這個規則類構造函數得到的參數,也可以通過指定正在處理的xml元素的屬性來傳遞一個新的類的名字。當end()方法被調用 時,棧頂的對象被彈出,Digester中對它的任何引用將被忽略。
    2. FactoryCreateRule,一個非常有用的ObjectCreateRule的變體。
    3. SetPropertiesRule,當begin()方法被調用時,digester 使用標準的Java Relection API來識別JavaBean的屬性設置方法(setter method),這些方法名稱中包含屬性(property)的名字,這些屬性與XML元素的屬性(attribute)匹配,于是這些方法被調用并將相應的屬性值(attribute value)傳給它們。這些自然的映射可以被重寫。建議不要過度使用這項功能,在大多數情況下,使用標準的BeanInfo機制會更好。
    4. SetPropertyRule,當begin()方法被調用時,digester調用棧頂對象的一個特定的屬性設置方法(property setter)并傳給它特定的值(property和值分別由兩個 attribute命名)。這對XML需要遵循一個指定的DTD時比較有用,你可以設置一個特別的屬性(property),雖然在指定DTD沒有attribute與其相對應。
    5. SetNextRule,當end()方法被調用時,digester分析第二棧頂元素,尋找一個特定屬性(property)的設置方法 (setter method),并接著調用這個方法,以棧頂的元素作參數。這個規則通常用來在兩個對象間建立1對多的關系,所用的方法也常被叫做addChild什么的。
    6. SetTopRule,當end()方法被調用時,digester分析棧頂元素,尋找一個特定屬性(property)的設置方法 (setter method),并接著調用這個方法,以第二棧頂的元素作參數。這個規則通常用來在兩個對象間建立1對多的關系,所用的方法也常被叫做setParent 什么的。
    7. CallMethodRule,這個規則設置當end()被調用時執行的棧頂對象的自定義方法,通過對這個規則的設置,來指定方法的名字、參數的數量以及定義的參數類型的Java類的名字。實際的參數值,來自激活這個方法的元素的子元素。
    8. CallParamRule,這個規則用來指定CallMethodRule的參數的值的來源,它可以來自一個特定的屬性,或子元素的body的內容.
    9. NodeCreateRule,一個特殊的規則,將對象樹的一部分轉換成一個DOM結點(Node),并壓入棧頂。

      對這些標準的規則類,可以創建它們的實例,并調用digester.addRule來注冊它們。由于經常使用它們,所以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學習筆記(二)

      為便于理解,將筆記的內容結構作了一些調整。

    對象棧

      對digester技術最普通的應用,是用來動態創建一個由Java對象構成的樹結構,各對象的屬性以及對象間的關系,基于XML文檔的內容來設置(XML文檔就是一棵樹)。為實現這種應用,Digester提供了一個對象棧,以供在相關的模板識別后被激活的處理規則操作。此棧的基本操作包括:
    1. clear(),清空棧的內容
    2. peek(),返回對棧頂對象的引用
    3. pop(),將棧頂對象彈出并返回
    4. push(),將一個新的對象壓入棧頂

      用棧的原因,就是當識別出一個XML元素的"開始"時,將相關對象生成并壓入棧頂,這個對象在處理該元素的子元素的過程中一直在棧中,當所有子元素都處理完后,解析器遇到這個元素的"結束"時,則彈出此對象,并進行相關的處理。
      如何描述對象間的關系呢?將棧頂的對象做為一個參數,傳遞給第二棧頂(即先于棧頂對象入棧的那個對象,在棧頂對象的下面)的一個方法,就可以簡單地建立起一種"父子關系",從而可以簡單地建立起1:1的關系(第二棧頂對象與棧頂對象之間)和1:N的關系(第二棧頂對象不動,N次壓棧頂彈棧頂對象).
      如果取得生成的第一個對象呢?可以讓parse()方法返回,或者在調用parse()方法前,先行壓入一個對象,在parse()方法結束后彈出這個對象,則其子對象即為我們想要的第一個對象。

    日志(logging)


      日志是一個調試Digester規則集的非常重要的工具,它可以記錄非常豐富的信息,因它在使用Digester之前有必要了解日志是如何工作的。
      Digester使用Jakarta Commons Logging,這個模塊并不是具體的日志實現,而只是一個可設置的接口。可以設置它將各種日志信息傳遞它自身帶的基本記錄器,或者傳遞給其它的更復雜的日志工具。具體請參考commons logging的文檔,或Jakarta Commons Logging學習筆記
      Digester主要使用兩個記錄器:
    1. SAX相關的信息,被送往org.apache.commons.digester.Digester.sax記錄器,記錄了Digester收到的SAX的事件的信息。
    2. 其它的所有信息,都被送往org.apache.commons. digester.Digester記錄器,這個記錄器在調試Digester時打開而在產品中常將其關閉

      假定用commons logging自帶的基本日志工具,并以DEBUG級別記錄Digester調試信息以及INFO級別記錄SAX事件信息,則對logging的配置文件設置如下:
    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>的屬性名字對映。當從xml文件中識別出<person> 的屬性時,如果有要求(即調用過addSetProperties方法),Digester會依據這種對映關系自動調用相應的方法。
    ??public?void?setId(int?id)?{
    ??????this.id?=?id;
    ??}
    ??public?void?setCategory(String?category)?{
    ??????this.category?=?category;
    ??}
    ? ?//對name而言,因為其值來自<name>標簽的內容而非屬性值,需要用addCallMethod指定識別< name>后的要調用此方法(想自動調用也要可以,需要addBeanPropertySetter,參見第下一個例子)。
    ??public?void?setName(String?name)?{
    ??????this.name?=?name;
    ??}
    ??//同name,此時還要一一指定addEmail的參數值的來源。
    ??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];
    ????????//?創建一個Digester實例
    ????????Digester?d?=?new?Digester();
    ????????//?創建AddressBook實例,并將其壓入棧頂。
    ????????AddressBook?book?=?new?AddressBook();
    ????????d.push(book);
    ????????//?增加規則
    ????????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);
    ????????}
    ????????
    ????????
    ????????//?將解析出的地址數據打印出來
    ????????book.print();
    ????}
    ????
    ????private?static?void?addRules(Digester?d)?{
    ????????//?當遇到<person>時,創建類Person的一個實例,并將其壓入棧頂
    ????????d.addObjectCreate("address-book/person",?Person.class);
    ????????
    ????????//?將<person>標簽的屬性(attribute)與棧頂Person類對象的屬性(property)設置方法根據各自的名字進行映射,(例如,將標簽屬性id與屬性設置方法setId進行映射,將標簽屬性category與屬性設置方法setCategory進行映射),然后將屬性的值作參數傳遞給執行相應的方法。
    ????????//?如果某標簽屬性沒法通過名字找到相應的屬性設置方法,則此標簽屬性被忽略(如example.xml中第一個<person>的try屬性)。
    ????????d.addSetProperties("address-book/person");

    ????????//?調用第二棧頂對象(AddressBook實例)的addPerson方法,以棧對象(Person實例)的對象為參數
    ????????d.addSetNext("address-book/person",?"addPerson");????????
    ????????
    ????????//?當遇到<person>的子元素<name>時,調用棧頂對象(Person實例)的setName方法。
    ????????//?此處addCallMethod方法的第一參數是規則,第二個參數是方法的名字,第三個是參數的數量(為0時,表示只有一個參數,且參數的值是元素的內容)
    ????????d.addCallMethod("address-book/person/name",?"setName",?0);
    ????????
    ????????//?當遇到<person>的子元素<email>時,調用棧頂對象(Person實例)的addEmail 方法,addEmail方法有兩個參數,取值分別來自<email>的屬性type的值和<email>本身的內容。
    ????????//?此處addCallParam方法的第一參數是規則,第二個參數是指明被調用方法(addEmail)參數的序號,第三個是參數為字符串時指屬性的名字)
    ????????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");
    ????}
    }

    運行結果如下(運行時可能需要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學習筆記(三)

      總覺得,Digester不僅僅能作配置文件解析,而且可以作得更多。

    配置屬性

      Digester用來解析應用系統的配置文件,其本身也有很可配置的屬性。
    屬性描述
    classLoader 指定類裝載器(class loader)。ObjectCreateRule 和 FactoryCreateRule兩個規則中,需要動態加載一些類(如那些盛放XML解析出來的數據的javaBean等),裝載器可以在次指定。如果不指定,對這此類的加載將會利用線程上下文中的加載器(當useContextClassLoader值為真時)或利用加載Digester的那個加載器。
    errorHandler 指定 SAX ErrorHandler,以在出現此類錯誤時調用。默認情況下,任何解析錯誤都會被記入日志,Digest會繼續進行解析。
    namespaceAware 一個布爾值,為真時對XML文件的解析時會考慮元素的域名空間(如不同的域名空間的同名元素會視為不同的元素)
    ruleNamespaceURI 指定后續加入的規則所屬的命名空間,如果此值為null,則加入的規則不與任何命名空間相聯系。
    rules 設定規則模板與XML元素的匹配處理程序。由于這個匹配程序是插件式的,所以匹配工作的完成可以用用戶定義的匹配程序未完成。默認情況下,使用Digester提供的匹配器。
    useContextClassLoader 一個布爾值,為真時FactoryCreateRule 和 ObjectCreateRule 兩個規則中對類的裝載將會采用當前線程上下文中指定的加載器。默認情況下,對類的動態加載會利用加載 Digester的那個裝載器。
    validating 一個布爾值,為真時解析器會根據DTD內容對XML文檔進行合法性檢查,默認值是假,解析器只是檢查XML是否格式良好(well formed).

      除了上述屬性外,還可以注冊一個本地DTD,以供DOCTYPE聲明引用。這樣的注冊告訴XML解析器,當遇到DOCTYPE聲明時,應使用剛注冊的DTD的內容,而不是DOCTYPE聲明中的標識符(identifier)。
      例如,Struect框架控制器中,使用下述的注冊,告訴Structs使用一個本地的DTD中的相關內容來處理Structs配置文件,這樣可以適用于那些沒有連接到互聯網的應用環境,而在連到互聯網的環境中可以加快運行速度(因為它避免了通過網絡去取相關的資源)。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());

    規則集打包


      通常情況下,一個規則被創建后,接著便注冊,然后等在event時被調用,這些規則集很難為其它應用程序直接復用。一個解決方法是將所有規則都放在一個類中,此由這些規則可以很簡單地被裝載然后被注冊使用。RuleSet接口就是為些而設計,一般是通過擴展RuleSetBase類來開發規則集類。如例:
    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");
    ??}
    }
    可以這樣使用這個規則集
    Digesterdigester = new Digester();
    ... 一些配置Digester ...
    digester.addRuleSet(new MyRuleSet("baz/"));

    帶命名空間的XML解析


      這種情況下,使用Digester的步驟為:
    1. Digester初始化部分,指明要考慮命名空間。
      digester.setNamespaceAware(true);

    2. 指明一些規則的命名空間,如
      digester.setRuleNamespaceURI(" http://www.mycompany.com/MyNamespace");

    3. 接下來定義一些與此命名空間有關的規則,此時可以省卻前綴,如
      digester.addObjectCreate("foo/bar", "com.mycompany.MyFoo");
      digester.addSetProperties("foo/bar");

    4. 對其它命名空間,重復前面的2步

      另外,在指明要digester考慮命名空間之后,在定義匹配模板時,可以將命名空間別名加":"作為元素名稱的一部分使用。這與無命名空間時是一致的。

    開發定制的匹配處理過程


      通過實現 org.apache.commons.digester.Rules接口或擴展org.apache.commons.digester.RulesBase類來達到定制匹配過程的目的。
      Digester提供ExtendedBaseRules來擴展了匹配模板的定義,引入了特殊通配字符?和*以及!,提供RegexRules來支持以正則式的語法定義匹配模板,提供WithDefaultsRulesWrapper來支持默認規則(即其它規則都不匹配時的處理規 則)。

    一些認識


      通過看說明材料,尤其在學習Digester包中的Catalog例子以后,有一些認識:
      1、由于xml對屬性名字的定義要求,與Java中對方法名字的定義要求不一致,導致出現不能自動映射的情況,如year-made標簽屬性,就不可能有方法setYear-made;
      2、對于根元素,與其子元素建立聯系,有幾種辦法:一種是先生成根元素實例,壓入棧,然后解析,將調用方法規則建立聯系;另一種是解析的過程中第一個創建它,然后用getRoot的方法得到。
      3、如果某對象類構造都要參數,則此時需要擴展AbstractObjectCreationFactory類為這種對象建立一個Factory,在這個Factory中取得初始化參數值然后再創建一個對象實例。
      4、設有某個標簽,要想自動用該標簽子元素的內容填充該標簽對應的對象的屬性,則需要用digester.setRules(new ExtendedBaseRules()),然后addRules(),然后再調用addBeanPropertySetter ("bala/lala/?");進行規則定義,注意此模板中有通配符。
      5、如果對象的屬性是整型,則Digester自動將xml文件中字符串值轉換為整型。
      6、在指明要digester考慮命名空間之后,如果不會引起歧義,完全可以忽略命名空間的存在,除非你要針對特定的命名空間進行特定的處理。
    posted on 2006-03-28 13:20 閱讀(507) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 久久精品国产亚洲av影院| 免费在线观看黄色毛片| 亚洲精品无码不卡在线播HE| 日韩免费高清一级毛片| 免费在线观看的黄色网址| 亚洲爆乳成av人在线视菜奈实| 毛片免费全部播放一级| 亚洲av永久无码精品三区在线4| 无码国产精品一区二区免费| 亚洲国产精品综合福利专区| 毛片免费vip会员在线看| 亚洲欧美日韩一区二区三区 | 午夜免费啪视频在线观看 | 久久伊人免费视频| 亚洲国产综合专区电影在线| 91精品国产免费入口| 亚洲精品偷拍无码不卡av| 一色屋成人免费精品网站| 亚洲国产午夜精品理论片在线播放 | 亚洲一区二区视频在线观看| 国产一区二区三区免费观在线| 亚洲日本在线观看| 黄瓜视频高清在线看免费下载 | 亚洲人成亚洲人成在线观看| 好紧我太爽了视频免费国产| 亚洲精品免费在线视频| 日日夜夜精品免费视频| 国产成人精品免费视频大全| 中文字幕亚洲精品资源网| 成人毛片18女人毛片免费96| 免费看一级高潮毛片| 亚洲欧洲在线观看| 免费观看的毛片手机视频| 4hu四虎免费影院www| 亚洲白色白色在线播放| 国产精品国产自线拍免费软件| 在线免费观看h片| 亚洲宅男精品一区在线观看| 亚洲无线一二三四区手机| 亚洲黄色免费在线观看| 午夜肉伦伦影院久久精品免费看国产一区二区三区 |