一个简单的例子
假定有两个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解析代码 |
注释 |
Digester digester = 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(); |
分析结束后,返回根元素。 |
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

|