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ī)則操作。此棧的基本操作包括:
用棧的原因,就是當識別出一個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主要使用兩個記錄器:
假定用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**********
運行結(jié)果如下(運行時可能需要xml-crimson,一個源sun的XML解析器,可到http://xml./crimson/下載)
<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(); ) { // 調(diào)用第二棧頂對象(AddressBook實例)的addPerson方法,以棧對象(Person實例)的對象為參數(shù) private static void usage() { 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 |
|
|