之类的结构)。
BeanPropertySetterRule:把顶层Bean的指定名称的属性设置成当前XML元素包含的字符数据。(通常用来处理<page>10</page>之类的结构)。
SetPropertyRule:设置顶层Bean的一个属性。无论是Bean属性的名称,还是赋予该属性的值,都在当前XML元素中以属性的形式指定,例如:<article key="page" value="10" />。
管理父/子关系
SetNextRule:弹出栈顶的对象,把它传递给紧接其下的另一个对象的指定名称的方法。通常用来把一个已经初始化的Bean插入到父对象。
SetTopRule:把栈里面上数第二的对象传递给顶层的对象。当子对象提供了一个setParenet方法时,这一规则很有用。
SetRootRule:调用栈底对象的一个方法,并把栈顶的对象作为参数传入。
调用任意方法
CallMethodRule:调用顶层Bean的指定名称的方法。被调用的方法可以有任意多个参数,参数的值通过后继的CallParamRule给出。
CallParamRule:表示方法调用的参数。参数的值或者取自指定名称的XML元素的属性,或者是当前元素包含的原始字符数据。这个规则要求用一个整数指定它在参数列表中的位置。
通过XML指定规则
在前面的内容中,我们用程序代码的方式指定模式和规则,这些模式和规则都是在编译的时候就已经确定,虽然从概念上来讲比较简单,但却不能说尽善尽美:Digester框架的总体目标是在运行时识别和处理各种数据结构,但如果我们用编程的方法指定模式和规则,则所有行为在编译时已经固定!如果Java源程序中包含了大量固定的字符串,通常意味着程序在执行某些配置操作,这部分操作可以被(或许是应该被)延迟到运行时进行。
org.apache.commons.digester.xmlrules包解决了这个问题。这个包提供了一个DigesterLoader类,它能够从XML文档读取模式/规则对,返回配置好的Digester对象。用来配置Digester对象的XML文档必须遵从digester-rules.dtd,这个DTD是xmlrules包的一部分。
下面就是本文例子的配置文件rules.xml。有几点必须说明。
首先,模式可以用两种方式指定:或者使用<pattern>元素,或者通过代表规则的XML元素的属性。这两种办法可以混合使用,且<pattern>元素是可以嵌套的。其次,<alias>元素和<set-properties-rule>一起使用,用来把XML属性映射到Bean属性。最后,就当前发行的Digester软件包而言,我们不能在配置文件中指定BeanPropertySetterRule,正如前面所介绍的,我们用CallMethodRule来达到同样的目标。
<?xml version="1.0"?>
<digester-rules>
<object-create-rule pattern="catalog" classname="Catalog" />
<set-properties-rule pattern="catalog" >
<alias attr-name="library" prop-name="library" />
</set-properties-rule>
<pattern value="catalog/book">
<object-create-rule classname="Book" />
<call-method-rule pattern="author" methodname="setAuthor"
paramcount="0" />
<call-method-rule pattern="title" methodname="setTitle"
paramcount="0" />
<set-next-rule methodname="addBook" />
</pattern>
<pattern value="catalog/magazine">
<object-create-rule classname="Magazine" />
<call-method-rule pattern="name" methodname="setName" paramcount="0" />
<pattern value="article">
<object-create-rule classname="Article" />
<set-properties-rule>
<alias attr-name="page" prop-name="page" />
</set-properties-rule>
<call-method-rule pattern="headline" methodname="setHeadline"
paramcount="0" />
<set-next-rule methodname="addArticle" />
</pattern>
<set-next-rule methodname="addMagazine" />
</pattern>
</digester-rules> |
现在,所有实际的操作都转移到了Digester和DigesterLoader类,XmlRulesDriver类就变得相当简单。运行下面的XmlRulesDriver时,在第一个命令行参数中指定目录文档的名字,在第二个参数中指定rules.xml(注意,DigesterLoader不是从File或者org.xml.sax.InputSource读取rules.xml文件,而是要求指定一个URL,因此,下面代码中File引用被转换成了等价的URL)。
import org.apache.commons.digester.*;
import org.apache.commons.digester.xmlrules.*;
import java.io.*;
import java.util.*;
public class XmlRulesDriver {
public static void main( String[] args ) {
try {
File input = new File( args[0] );
File rules = new File( args[1] );
Digester digester = DigesterLoader.createDigester( rules.toURL() );
Catalog catalog = (Catalog)digester.parse( input );
System.out.println( catalog.toString() );
} catch( Exception exc ) {
exc.printStackTrace();
}
}
} |
结束语:本文对Jakarta Commons Digester的介绍就到这里结束。当然,还有许多内容这里尚未涉及。其中一个在这里忽略的主题是XML名称空间:Digester允许把规则定义成只能对某一个名称空间内定义的元素起作用。
另外,我们简单地提及了通过扩展Rule类开发定制规则的问题。按照习惯,Digester类提供了push()、peek()和pop()方法,使得开发者能够自由地直接操作解析栈。
参考:
Jakarta Commons Digester Homepage
Jakarta Struts Homepage
(责任编辑 Sunny)
<<上一页
1
2