Digester学习笔记
程序中用到的文件Example.xml (程序解析的xml文件)
1
<?
xml version="1.0" encoding="UTF-8"
?>
2
3 < address-book >
4 < person id ="1" category ="acquaintance" try ="would be ignored" >
5
6 < name > Gonzo </ name >
7
8 < email type ="business" > [email protected] </ email >
9
10 < gender result ="the whole tag would be ignored" > male </ gender >
11
12 </ person >
13
14 < person id ="2" category ="rolemodel" >
15
16 < name > Kermit </ name >
17
18 < email type ="business" > [email protected] </ email >
19
20 < email type ="home" > [email protected] </ email >
21
22 </ person >
23
24 </ address-book >
2
3 < address-book >
4 < person id ="1" category ="acquaintance" try ="would be ignored" >
5
6 < name > Gonzo </ name >
7
8 < email type ="business" > [email protected] </ email >
9
10 < gender result ="the whole tag would be ignored" > male </ gender >
11
12 </ person >
13
14 < person id ="2" category ="rolemodel" >
15
16 < name > Kermit </ name >
17
18 < email type ="business" > [email protected] </ email >
19
20 < email type ="home" > [email protected] </ email >
21
22 </ person >
23
24 </ address-book >
Person.java :
1
package
digester.test;
2
3 import java.util.HashMap;
4 import java.util.Iterator;
5
6 public class Person {
7 private int id;
8 private String category;
9 private String name;
10 private HashMap < String, String > emails = new HashMap < String, String > ();
11 // 下面的两个方法的名字中set以后的部分,与</person>的属性名字对应
12 // 当从xml文件中识别出<person>的属性时,如果有要求(即调用过addSetProperties方法),Digester会依据这种对映关系自动调用相应的方法。
13
14 public void setId( int id){
15 this .id = id;
16 }
17 public void setCategory(String category) {
18 this .category = category;
19 }
20
21 // 对应name而言,因为其值来自name标签的内容,而非属性值
22 // 需要调用addCallMethod指定识别<name>后调用此方法,自动调用,需调用addBeanPropertySetter()方法
23
24 public void setName(String name) {
25 this .name = name;
26 }
27 // 同name,此时还要一一指定addEmail的参数值的来源。
28 public void addEmail(String type, String address) {
29 emails.put(type, address);
30 }
31 public void print() {
32
33 System.out.println( " Person # " + id);
34
35 System.out.println( " category= " + category);
36
37 System.out.println( " name= " + name);
38
39 for (Iterator i = emails.keySet().iterator(); i.hasNext(); ) {
40
41 String type = (String) i.next();
42
43 String address = (String) emails.get(type);
44
45 System.out.println( " email (type " + type + " ) : " + address);
46
47 }
48
49 }
50
51 }
52
2
3 import java.util.HashMap;
4 import java.util.Iterator;
5
6 public class Person {
7 private int id;
8 private String category;
9 private String name;
10 private HashMap < String, String > emails = new HashMap < String, String > ();
11 // 下面的两个方法的名字中set以后的部分,与</person>的属性名字对应
12 // 当从xml文件中识别出<person>的属性时,如果有要求(即调用过addSetProperties方法),Digester会依据这种对映关系自动调用相应的方法。
13
14 public void setId( int id){
15 this .id = id;
16 }
17 public void setCategory(String category) {
18 this .category = category;
19 }
20
21 // 对应name而言,因为其值来自name标签的内容,而非属性值
22 // 需要调用addCallMethod指定识别<name>后调用此方法,自动调用,需调用addBeanPropertySetter()方法
23
24 public void setName(String name) {
25 this .name = name;
26 }
27 // 同name,此时还要一一指定addEmail的参数值的来源。
28 public void addEmail(String type, String address) {
29 emails.put(type, address);
30 }
31 public void print() {
32
33 System.out.println( " Person # " + id);
34
35 System.out.println( " category= " + category);
36
37 System.out.println( " name= " + name);
38
39 for (Iterator i = emails.keySet().iterator(); i.hasNext(); ) {
40
41 String type = (String) i.next();
42
43 String address = (String) emails.get(type);
44
45 System.out.println( " email (type " + type + " ) : " + address);
46
47 }
48
49 }
50
51 }
52
AddressBook.java
1
package
digester.test;
2
3 import java.util.Iterator;
4 import java.util.LinkedList;
5
6 public class AddressBook {
7 LinkedList people = new LinkedList();
8
9 public void addPerson(Person p) {
10 people.addLast(p);
11 }
12 public void print() {
13 System.out.println( " Address book has " + people.size() + " entries " );
14 for (Iterator i = people.iterator(); i.hasNext(); ) {
15 Person p = (Person) i.next();
16 p.print();
17 }
18
19 }
20 public void digest() {
21 // TODO Auto-generated method stub
22
23 }
24
25
26 }
27
2
3 import java.util.Iterator;
4 import java.util.LinkedList;
5
6 public class AddressBook {
7 LinkedList people = new LinkedList();
8
9 public void addPerson(Person p) {
10 people.addLast(p);
11 }
12 public void print() {
13 System.out.println( " Address book has " + people.size() + " entries " );
14 for (Iterator i = people.iterator(); i.hasNext(); ) {
15 Person p = (Person) i.next();
16 p.print();
17 }
18
19 }
20 public void digest() {
21 // TODO Auto-generated method stub
22
23 }
24
25
26 }
27
主类:AddressBookDigester.java
1
package
digester.test;
2
3 import org.apache.commons.digester.Digester;
4 /**
5 * digester技术最普通的应用,就是用来动态创建一个由java对象构成的树结构,各对象的属性以及对象间的关系。
6 * 是基于xml文档的内容来设置的。为实现这种应用,Digester提供了一个对象栈
7 * clear(),清空栈的内容;peek(),返回对栈顶对象的引用;pop(),将栈顶对象弹出并返回;push(),将一个新的对象压入栈顶。
8 * 用栈的原因:
9 * 当识别一个xml元素的开始,创建对象并压人栈顶。这个对象在处理该元素的子元素过程中一直在栈中,
10 * 当所有子元素处理完后,解析器遇到该元素的结束标记,弹出此对象,并进行相应的处理。
11 * 描述对象间的关系:
12 * 将栈顶对象作为一个参数,传递给该对象的下面的对象的一个方法,就可以简单的建立父子关系。
13 * 从而可以简单地建立起1:1的关系(第二栈顶对象与栈顶对象之间)和1:N的关系(第二栈顶对象不动,N次压栈顶弹栈顶对象)
14 *
15 */
16 public class AddressBookDigester {
17 public static void main(String[] args) throws Exception {
18 AddressBookDigester d = new AddressBookDigester();
19 // 创建一个Digester实例
20 // 当遇到匹配元素的开始标记和结束标记时,begin()方法和end()方法将分别被调用。
21 Digester digester = new Digester();
22 // 创建AddressBook实例,并将其压入栈顶。
23 AddressBook book = new AddressBook();
24 digester.push(book);
25 // 增加规则
26 addRules(digester);
27 java.io.File srcfile = new java.io.File( " ../struts/src/Example.xml " );
28 digester.parse(srcfile);
29 book.print();
30 }
31
32 private static void addRules(Digester digester) {
33
34 // 当遇到<person>时,创建类Person的一个实例,并将其压入栈顶
35 // 当元素被处理结束时,对象被弹出。
36 digester.addObjectCreate( " address-book/person " , Person. class );
37
38 // 将<person>标签的属性(attribute)与栈顶Person类对象的属性(property)设置方法根据各自的名字进行映射,
39 // (例如,将标签属性id与属性设置方法setId进行映射,将标签属性category与属性设置方法setCategory进行映射),
40 // 然后将属性的值作参数传递给执行相应的方法。
41
42 // 如果某标签属性没法通过名字找到相应的属性设置方法,则此标签属性被忽略(如example.xml中第一个<person>的try属性)。
43
44 digester.addSetProperties( " address-book/person " );
45
46 // 调用第二栈顶对象(AddressBook实例)的addPerson方法,以栈对象(Person实例)的对象为参数
47 // 配置完毕的Bean插入父对象。
48
49 // 弹出栈顶的对象,把它传递给紧接其下的另一个对象的指定名称的方法。
50 // 通常用来把一个已经初始化的Bean插入到父对象。
51
52 digester.addSetNext( " address-book/person " , " addPerson " );
53
54 // 当遇到<person>的子元素<name>时,调用栈顶对象(Person实例)的setName方法。
55
56 // 此处addCallMethod方法的第一参数是规则,第二个参数是方法的名字,
57 // 第三个是参数的数量(为0时,表示只有一个参数,且参数的值是元素的内容
58
59 // 调用顶层Bean的指定名称的方法。
60 // 被调用的方法可以有任意多个参数,参数的值通过后继的CallParamRule给出。
61
62 digester.addCallMethod( " address-book/person/name " , " setName " , 0 );
63
64 // 当遇到<person>的子元素<email>时,调用栈顶对象(Person实例)的addEmail方法,
65 // addEmail方法有两个参数,取值分别来自<email>的属性type的值和<email>本身的内容。
66
67 // 此处addCallParam方法的第一参数是规则,第二个参数是指明被调用方法(addEmail)参数的序号,第三个是参数为字符串时指属性的名字)
68 // 表示方法调用的参数。参数的值取自指定名称的XML元素的属性,或者是当前元素包含的原始字符数据。
69 // 这个规则要求用一个整数指定它在参数列表中的位置。
70
71 digester.addCallMethod( " address-book/person/email " , " addEmail " , 2 );
72 digester.addCallParam( " address-book/person/email " , 0 , " type " );
73 digester.addCallParam( " address-book/person/email " , 1 );
74
75 }
76
77
78 }
79
2
3 import org.apache.commons.digester.Digester;
4 /**
5 * digester技术最普通的应用,就是用来动态创建一个由java对象构成的树结构,各对象的属性以及对象间的关系。
6 * 是基于xml文档的内容来设置的。为实现这种应用,Digester提供了一个对象栈
7 * clear(),清空栈的内容;peek(),返回对栈顶对象的引用;pop(),将栈顶对象弹出并返回;push(),将一个新的对象压入栈顶。
8 * 用栈的原因:
9 * 当识别一个xml元素的开始,创建对象并压人栈顶。这个对象在处理该元素的子元素过程中一直在栈中,
10 * 当所有子元素处理完后,解析器遇到该元素的结束标记,弹出此对象,并进行相应的处理。
11 * 描述对象间的关系:
12 * 将栈顶对象作为一个参数,传递给该对象的下面的对象的一个方法,就可以简单的建立父子关系。
13 * 从而可以简单地建立起1:1的关系(第二栈顶对象与栈顶对象之间)和1:N的关系(第二栈顶对象不动,N次压栈顶弹栈顶对象)
14 *
15 */
16 public class AddressBookDigester {
17 public static void main(String[] args) throws Exception {
18 AddressBookDigester d = new AddressBookDigester();
19 // 创建一个Digester实例
20 // 当遇到匹配元素的开始标记和结束标记时,begin()方法和end()方法将分别被调用。
21 Digester digester = new Digester();
22 // 创建AddressBook实例,并将其压入栈顶。
23 AddressBook book = new AddressBook();
24 digester.push(book);
25 // 增加规则
26 addRules(digester);
27 java.io.File srcfile = new java.io.File( " ../struts/src/Example.xml " );
28 digester.parse(srcfile);
29 book.print();
30 }
31
32 private static void addRules(Digester digester) {
33
34 // 当遇到<person>时,创建类Person的一个实例,并将其压入栈顶
35 // 当元素被处理结束时,对象被弹出。
36 digester.addObjectCreate( " address-book/person " , Person. class );
37
38 // 将<person>标签的属性(attribute)与栈顶Person类对象的属性(property)设置方法根据各自的名字进行映射,
39 // (例如,将标签属性id与属性设置方法setId进行映射,将标签属性category与属性设置方法setCategory进行映射),
40 // 然后将属性的值作参数传递给执行相应的方法。
41
42 // 如果某标签属性没法通过名字找到相应的属性设置方法,则此标签属性被忽略(如example.xml中第一个<person>的try属性)。
43
44 digester.addSetProperties( " address-book/person " );
45
46 // 调用第二栈顶对象(AddressBook实例)的addPerson方法,以栈对象(Person实例)的对象为参数
47 // 配置完毕的Bean插入父对象。
48
49 // 弹出栈顶的对象,把它传递给紧接其下的另一个对象的指定名称的方法。
50 // 通常用来把一个已经初始化的Bean插入到父对象。
51
52 digester.addSetNext( " address-book/person " , " addPerson " );
53
54 // 当遇到<person>的子元素<name>时,调用栈顶对象(Person实例)的setName方法。
55
56 // 此处addCallMethod方法的第一参数是规则,第二个参数是方法的名字,
57 // 第三个是参数的数量(为0时,表示只有一个参数,且参数的值是元素的内容
58
59 // 调用顶层Bean的指定名称的方法。
60 // 被调用的方法可以有任意多个参数,参数的值通过后继的CallParamRule给出。
61
62 digester.addCallMethod( " address-book/person/name " , " setName " , 0 );
63
64 // 当遇到<person>的子元素<email>时,调用栈顶对象(Person实例)的addEmail方法,
65 // addEmail方法有两个参数,取值分别来自<email>的属性type的值和<email>本身的内容。
66
67 // 此处addCallParam方法的第一参数是规则,第二个参数是指明被调用方法(addEmail)参数的序号,第三个是参数为字符串时指属性的名字)
68 // 表示方法调用的参数。参数的值取自指定名称的XML元素的属性,或者是当前元素包含的原始字符数据。
69 // 这个规则要求用一个整数指定它在参数列表中的位置。
70
71 digester.addCallMethod( " address-book/person/email " , " addEmail " , 2 );
72 digester.addCallParam( " address-book/person/email " , 0 , " type " );
73 digester.addCallParam( " address-book/person/email " , 1 );
74
75 }
76
77
78 }
79
以上的程序来源网络,我真理了一下。
附件: http://www.blogjava.net/Files/windfree/test.rar