Posted on 2006-07-18 12:20
Earth 阅读(337)
评论(0) 编辑 收藏 所属分类:
Java
这里是在Eclipse下的展开图:
下载源代码download
今天初学了一下Digester,并把它在Eclipse下跑了一遍,呵呵。学会开始用ant来构建任务了。发现如同JBuilder一样也可以直接在TestDigester上使用Alt+Shift+X来运行main函数,不错。
网上的例子只有一个大致的皮毛,我把这个foo ,bar的例子实际实现了一遍(后来发现Digester src包中给我们提供了几个更好的例子,不错)。使用Digester的步骤大致如下:
//
首先要new一个Digester对象
Digester digester
=
new
Digester();
//
不进行XML与相应的DTD的合法性验证
digester.setValidating(
false
);
//
当遇到<foo>时创建一个test.Foo对象,并将其放在栈顶
digester.addObjectCreate(
"
foo
"
,
"
test.Foo
"
);
//
根据<foo>元素的属性(这里是name),对刚创建的Foo对象的属性(这里也是name)进行设置
//
注:xml中的属性称为attribute,对象中的属性称为property
digester.addSetProperties(
"
foo
"
);
//
当遇到<foo>的子元素<bar>时创建一个test.Bar对象,并将其放在栈顶。
digester.addObjectCreate(
"
foo/bar
"
,
"
test.Bar
"
);
//
根据<bar>元素的属性,对刚创建的Bar对象的属性进行设置,这里有两个:分别是id和title
digester.addSetProperties(
"
foo/bar
"
);
//
当再次遇到<foo>的子元素<bar>时创建一个test.Bar对象,并将其放在栈顶,同时调用第二栈顶元素(Foo对象)的addBar方法。
digester.addSetNext(
"
foo/bar
"
,
"
addBar
"
,
"
test.Bar
"
);
ClassLoader classLoader
=
Thread.currentThread()
.getContextClassLoader();
InputStream in
=
classLoader.getResourceAsStream(
"
Foobar.xml
"
);
Foo foo
=
null
;
try
{
if
(in
!=
null
)
{
foo
=
(Foo) digester.parse(in);
//
分析结束后,返回根元素。
}
}
catch
(IOException e)
{
e.printStackTrace();
}
catch
(SAXException e)
{
e.printStackTrace();
}
元素匹配模式
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>都可匹配(不包括根元素级的).
处理规则
元素匹配模式用于确定什么时候进行处理,而处理规则则用于定义处理的内容,也就是进行什么样的行动。
Digester定义了一系列的常用的处理规则。在设置Digester时,可能通过调用addRule()方法来注册一个特定的元素匹配模式以及一个相应的处理规则类的实例。
用户也可以自定义一些自己的处理规则类,用于满足不同类型的特殊需求。定义一个处理规则首先要扩展org.apache.commons.digester.Rule类。然后再根据特殊的要求来实现begin(), body(), end(), finish()事件处理方法。
对于一些标准的规则类,可以创建它们的实例,并调用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");
在前面的foo, bar例子中,从log4j打印出的信息可以窥见它所用到的处理规则
New match='foo'
[ObjectCreateRule]{foo}New test.Foo
[SetPropertiesRule]{foo} Setting property 'name' to 'The Parent'
New match='foo/bar'
[ObjectCreateRule]{foo/bar}New test.Bar
[SetPropertiesRule]{foo/bar} Setting property 'id' to '123'
[SetPropertiesRule]{foo/bar} Setting property 'title' to 'The First Child'
[SetNextRule]{foo/bar} Call test.Foo.addBar(test.Bar@30c221[id=123,title=The First Child])