小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

竹筍炒肉: Digester學習筆記(二)

 shaobin0604@163.com 2007-01-24

Digester學習筆記(二)

  為便于理解,將筆記的內(nèi)容結(jié)構(gòu)作了一些調(diào)整。

對象棧

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

  用棧的原因,就是當識別出一個XML元素的“開始”時,將相關(guān)對象生成并壓入棧頂,這個對象在處理該元素的子元素的過程中一直在棧中,當所有子元素都處理完后,解析器遇到這個元素的“結(jié)束”時,則彈出此對象,并進行相關(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,這個模塊并不是具體的日志實現(xiàn),而只是一個可設(shè)置的接口??梢栽O(shè)置它將各種日志信息傳遞它自身帶的基本記錄器,或者傳遞給其它的更復雜的日志工具。具體請參考commons logging的文檔,或Jakarta Commons Logging學習筆記
  Digester主要使用兩個記錄器:
  1. SAX相關(guān)的信息,被送往org.apache.commons.digester.Digester.sax記錄器,記錄了Digester收到的SAX的事件的信息。
  2. 其它的所有信息,都被送往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>的屬性名字對映。當從xml文件中識別出<person>的屬性時,如果有要求(即調(diào)用過addSetProperties方法),Digester會依據(jù)這種對映關(guān)系自動調(diào)用相應的方法。
  public void setId(int id) {
      this.id = id;
  }
  public void setCategory(String category) {
      this.category = category;
  }
  //對name而言,因為其值來自<name>標簽的內(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實例
        Digester d = new Digester();
        // 創(chuàng)建AddressBook實例,并將其壓入棧頂。
        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) {
        // 當遇到<person>時,創(chuàng)建類Person的一個實例,并將其壓入棧頂
        d.addObjectCreate("address-book/person", Person.class);
        
        // 將<person>標簽的屬性(attribute)與棧頂Person類對象的屬性(property)設(shè)置方法根據(jù)各自的名字進行映射,(例如,將標簽屬性id與屬性設(shè)置方法setId進行映射,將標簽屬性category與屬性設(shè)置方法setCategory進行映射),然后將屬性的值作參數(shù)傳遞給執(zhí)行相應的方法。
        // 如果某標簽屬性沒法通過名字找到相應的屬性設(shè)置方法,則此標簽屬性被忽略(如example.xml中第一個<person>的try屬性)。
        d.addSetProperties("address-book/person");

        // 調(diào)用第二棧頂對象(AddressBook實例)的addPerson方法,以棧對象(Person實例)的對象為參數(shù)
        d.addSetNext("address-book/person", "addPerson");        
        
        // 當遇到<person>的子元素<name>時,調(diào)用棧頂對象(Person實例)的setName方法。
        // 此處addCallMethod方法的第一參數(shù)是規(guī)則,第二個參數(shù)是方法的名字,第三個是參數(shù)的數(shù)量(為0時,表示只有一個參數(shù),且參數(shù)的值是元素的內(nèi)容)
        d.addCallMethod("address-book/person/name", "setName", 0);
        
        // 當遇到<person>的子元素<email>時,調(diào)用棧頂對象(Person實例)的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");
    }
}

運行結(jié)果如下(運行時可能需要xml-crimson,一個源sun的XML解析器,可到http://xml./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

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多