- 浏览: 234088 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
Navee:
抄来抄去,还是没有实质解决问题
Ext 树.叶子查找与非叶子查找 -
haizhiguang:
我按照你的代码自己写了一个试试,没看出我的代码跟你的有什么区别 ...
JAVA 鼠标画直线举行椭圆 -
WHW1984:
整个工程目录结构是咋样的 兄弟
Jetty -- 安全认证 -- 三种配置方法 -
shixianwei:
...
Jetty Oracle DataSource Config(Jetty Oracle 数据源配置) -
cpusoft:
http://cuiyingfeng.blog.ccidnet ...
JNI(java 调用 本地接口)Tomcat的JNI库加载问题解决办法
用digester简化xml文档处理java 2010-05-04 17:29:33 阅读6 评论0 字号:大中小
digester框架属于 jakarta commons,它以规则和模式为基础处理xml文档。与sax和dom之类的标准api相比,digester不涉及太多的细节问题,非常适合于对 xml文档进行简单的处理。
在java和xml开发中,一个常见的任务是把xml文档转换成对应的java bean对象的层次结构。人们经常用标准的sax和dom api来完成这个任务。虽然这两种api都很强大和灵活,但对于某些简单的任务来说,它们显得操作层次太低,也就是说,涉及了太多的细节问题。 jakarta digester框架能够很好地满足这类场合的需要。
digester框架简介
jakarta的digester框架从struts框架发展而来,原先被用来处理struts-config.xml配置文件,但很快人们认识到它有着更广泛的用途,把它转入了jakarta commons项目。jakarta commons的目标是提供一个“可重用java组件的仓库”。digester最新的版本是1.3,于2002年8月13日发布。
digester框架允许开发者指定一组动作,当解析器在xml文档中发现某些特定的简单模式时动作被执行。digester框架带有10个预定义的规则(rule),涵盖了unmarshalling xml(例如创建bean或设置bean属性)的大多数需求( marshalling的原意是指“配制整齐,编组列车”,marshalling是在内存中为java对象生成xml描述文档的过程,而 unmarshalling是指把xml形式的描述转换到可用java代码操作的对象的过程,我们称之为“反配制”),但必要时用户可以定义和实现自己的规则。
在本文的例子中,我们将反配制下面这个xml文档:
<?xml version="1.0"?>
<catalog library="somewhere">
<book>
<author>author 1</author>
<title>title 1</title>
</book>
<book>
<author>author 2</author>
<title>his one book</title>
</book>
<magazine>
<name>mag title 1</name>
<article page="5">
<headline>some headline</headline>
</article>
<article page="9">
<headline>another headline</headline>
</article>
</magazine>
<book>
<author>author 2</author>
<title>his other book</title>
</book>
<magazine>
<name>mag title 2</name>
<article page="17">
<headline>second headline</headline>
</article>
</magazine>
</catalog>
下面是bean的代码。注意使用digester框架时,bean类必须定义成public。
import java.util.vector;
public class catalog {
private vector books;
private vector magazines;
public catalog() {
books = new vector();
magazines = new vector();
}
public void addbook( book rhs ) {
books.addelement( rhs );
}
public void addmagazine( magazine rhs ) {
magazines.addelement( rhs );
}
public string tostring() {
string newline = system.getproperty( "line.separator" );
stringbuffer buf = new stringbuffer();
buf.append( "--- books ---" ).append( newline );
for( int i=0; i<books.size(); i++ ){
buf.append( books.elementat(i) ).append( newline );
}
buf.append( "--- magazines ---" ).append( newline );
for( int i=0; i<magazines.size(); i++ ){
buf.append( magazines.elementat(i) ).append( newline );
}
return buf.tostring();
}
}
//===================================================
public class book {
private string author;
private string title;
public book() {}
public void setauthor( string rhs ) { author = rhs; }
public void settitle( string rhs ) { title = rhs; }
public string tostring() {
return "book: author='" + author + "' title='" + title + "'";
}
}
//===================================================
import java.util.vector;
public class magazine {
private string name;
private vector articles;
public magazine() {
articles = new vector();
}
public void setname( string rhs ) { name = rhs; }
public void addarticle( article a ) {
articles.addelement( a );
}
public string tostring() {
stringbuffer buf = new stringbuffer( "magazine: name='" + name + "' ");
for( int i=0; i<articles.size(); i++ ){
buf.append( articles.elementat(i).tostring() );
}
return buf.tostring();
}
}
//===================================================
public class article {
private string headline;
private string page;
public article() {}
public void setheadline( string rhs ) { headline = rhs; }
public void setpage( string rhs ) { page = rhs; }
public string tostring() {
return "article: headline='" + headline + "' on page='" + page + "' ";
}
}
指定模式和规则
digester框架以模式(pattern)和规则(rule)为基础处理输入的xml。模式必须与xml元素匹配,包括其名字和在文档树内的位置。描述匹配模式的语法类似于xpath匹配模式,例如:catalog模式匹配顶层的<catalog>元素,catalog/book模式匹配直接嵌套在<catalog>元素内的<book>元素(但不匹配文档内其他位置的<book>元素)。
所有的模式都必须指定其完整名称——从根元素开始的完整路径。唯一的例外是包含通配符(“*”)的模式,例如*/name模式匹配xml文档内任何位置的<name>元素。但是根元素不必特别指出,因为所有的路径都是从根元素开始的绝对路径。
当digester发现一个指定的模式,它就执行关联的任务。由此可见,digester框架显然与sax解析器有着密切的关系(实际上,digester类实现了org.xml.sax.contenthandler,并维护着解析栈)。所有在digester中使用的规则必须扩展 org.apache.commons.digester.rule,后者本身提供了一些类似于sax的contenthandler回调函数的方法。例如,当遇到匹配元素的开始标记和结束标记时,begin()方法和end()方法将分别被调用。
一旦遇到匹配元素的内容,body()方法被调用;最后被调用的方法是finish(),这个方法在匹配元素的结束标记处理完毕之后被调用,用来执行可能需要的事后清理任务。然而,大多数时候我们不必关注这些方法,因为框架提供的标准规则很可能已经提供了所有必需的功能。
要反配制一个文档,首先创建一个org.apache.commons.digester.digester类的实例,如果必要的话,进行一些配置操作,指定必需的模式和规则,最后向parse()方法传递一个xml文件的引用。下面的digesterdriver示范了这一处理过程(必须在命令行上指定输入xml文档的名称)。
import org.apache.commons.digester.*;
import java.io.*;
import java.util.*;
public class digesterdriver {
public static void main( string[] args ) {
try {
digester digester = new digester();
digester.setvalidating( false );
digester.addobjectcreate( "catalog", catalog.class );
digester.addobjectcreate( "catalog/book", book.class );
digester.addbeanpropertysetter( "catalog/book/author", "author" );
digester.addbeanpropertysetter( "catalog/book/title", "title" );
digester.addsetnext( "catalog/book", "addbook" );
digester.addobjectcreate( "catalog/magazine", magazine.class );
digester.addbeanpropertysetter( "catalog/magazine/name", "name" );
digester.addobjectcreate( "catalog/magazine/article", article.class );
digester.addsetproperties( "catalog/magazine/article", "page", "page" );
digester.addbeanpropertysetter( "catalog/magazine/article/headline" );
digester.addsetnext( "catalog/magazine/article", "addarticle" );
digester.addsetnext( "catalog/magazine", "addmagazine" );
file input = new file( args[0] );
catalog c = (catalog)digester.parse( input );
system.out.println( c.tostring() );
} catch( exception exc ) {
exc.printstacktrace();
}
}
}
在上面的代码中,我们首先创建了digester类的一个实例digester,然后指定它不要用dtd验证xml文档的合法性——这是因为我们没有为xml文档定义dtd。接下来,我们指定了模式和关联的规则:objectcreaterule创建指定类的一个实例,并将它压入解析栈。 setpropertiesrule把bean属性设置成当前xml元素的属性值——规则的第一个参数是xml属性的名称,第二个参数是bean属性的名称。
setpropertiesrule获取的是xml属性的值,而beanpropertysetterrule获取的是位于当前元素内的原始字符数据值。使用 beanpropertysetterrule时不必指定要设置的bean属性名字,默认是当前xml元素的名称。在上面的例子中,在匹配 catalog/magazine/article/headline模式的规则定义中使用的就是默认值。最后,setnextrule弹出解析栈顶部的对象,并把该对象传递给它下面对象的指定名称的方法——通常用来把一个配置完毕的bean插入父对象。
注意,我们可以为同一个模式注册多个规则。如果注册了多个规则,则这些规则按照它们被加入到digester的次序执行,例如,如果要处理 catalog/magazine/article的元素,我们首先创建合适的article bean,然后设置page属性,最后弹出完成后的article bean,并把它插入magazine。
调用任意方法
我们不仅可以设置bean的属性,而且还可以调用堆栈内对象的任意方法。这通过callmethodrule完成,我们只需指定方法名字,如有必要,再说明调用的参数类型和数量。callparamrule用来定义传递给被调用函数的参数值,参数值可以从当前xml元素的命名的属性获取,也可以从当前元素包含的原始字符数据获取。例如,在前面实现digesterdriver的例子中,我们可以不用beanpropertysetterrule,而是通过显式调用属性的set方法达到同样的目的:
digester.addcallmethod( "catalog/book/author", "setauthor", 1 );
digester.addcallparam( "catalog/book/author", 0 );
上面的第一行代码给出了要调用的方法(即setauthor()),以及该调用需要的参数数量(即1)。第二行代码的意思是从元素包含的字符数据获取函数参数的值,把它作为参数数组的第一个传入(即索引是0的数组元素)。如果我们指定了xml元素属性的名称(例如 digester.addcallparam( "catalog/book/author", 0, "author" );),则参数值将从当前元素的相应属性值获取。
这里必须注意的是,“digester.addcallmethod( "pattern", "methodname", 0 );”这个语句不是指定了一个不带参数的方法调用,而是指定了带有一个参数的方法调用,它的值就是当前xml元素的字符数据!这样,我们又有了另一种替代 beanpropertysetterrule的办法:
digester.addcallmethod( "catalog/book/author", "setauthor", 0 );
如果要调用一个确实没有参数的方法,必须采用如下形式:digester.addcallmethod( "pattern", "methodname" );。
标准规则概要
下面简要说明所有标准规则。
创建
objectcreaterule:利用指定类的默认构造函数,创建该类的一个对象,并把对象压入栈。当元素处理结束时,对象被弹出。被实例化的类可通过class对象或类的全称给出。
factorycreaterule:利用指定的工厂类创建一个对象,把对象压入栈。对于没有提供默认构造函数的类,这一规则很有用。用于该规则的工厂类必须实现org.apache.commons.digester.objectcreationfactory接口。
设置属性
setpropertiesrule:利用指定名称的xml元素属性值,设置顶层bean的一个或者多个指定名称的属性。xml元素的属性名称和 bean的属性名称以string[]数组形式传入该规则(通常用来处理之类的结构)。
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
digester框架属于 jakarta commons,它以规则和模式为基础处理xml文档。与sax和dom之类的标准api相比,digester不涉及太多的细节问题,非常适合于对 xml文档进行简单的处理。
在java和xml开发中,一个常见的任务是把xml文档转换成对应的java bean对象的层次结构。人们经常用标准的sax和dom api来完成这个任务。虽然这两种api都很强大和灵活,但对于某些简单的任务来说,它们显得操作层次太低,也就是说,涉及了太多的细节问题。 jakarta digester框架能够很好地满足这类场合的需要。
digester框架简介
jakarta的digester框架从struts框架发展而来,原先被用来处理struts-config.xml配置文件,但很快人们认识到它有着更广泛的用途,把它转入了jakarta commons项目。jakarta commons的目标是提供一个“可重用java组件的仓库”。digester最新的版本是1.3,于2002年8月13日发布。
digester框架允许开发者指定一组动作,当解析器在xml文档中发现某些特定的简单模式时动作被执行。digester框架带有10个预定义的规则(rule),涵盖了unmarshalling xml(例如创建bean或设置bean属性)的大多数需求( marshalling的原意是指“配制整齐,编组列车”,marshalling是在内存中为java对象生成xml描述文档的过程,而 unmarshalling是指把xml形式的描述转换到可用java代码操作的对象的过程,我们称之为“反配制”),但必要时用户可以定义和实现自己的规则。
在本文的例子中,我们将反配制下面这个xml文档:
<?xml version="1.0"?>
<catalog library="somewhere">
<book>
<author>author 1</author>
<title>title 1</title>
</book>
<book>
<author>author 2</author>
<title>his one book</title>
</book>
<magazine>
<name>mag title 1</name>
<article page="5">
<headline>some headline</headline>
</article>
<article page="9">
<headline>another headline</headline>
</article>
</magazine>
<book>
<author>author 2</author>
<title>his other book</title>
</book>
<magazine>
<name>mag title 2</name>
<article page="17">
<headline>second headline</headline>
</article>
</magazine>
</catalog>
下面是bean的代码。注意使用digester框架时,bean类必须定义成public。
import java.util.vector;
public class catalog {
private vector books;
private vector magazines;
public catalog() {
books = new vector();
magazines = new vector();
}
public void addbook( book rhs ) {
books.addelement( rhs );
}
public void addmagazine( magazine rhs ) {
magazines.addelement( rhs );
}
public string tostring() {
string newline = system.getproperty( "line.separator" );
stringbuffer buf = new stringbuffer();
buf.append( "--- books ---" ).append( newline );
for( int i=0; i<books.size(); i++ ){
buf.append( books.elementat(i) ).append( newline );
}
buf.append( "--- magazines ---" ).append( newline );
for( int i=0; i<magazines.size(); i++ ){
buf.append( magazines.elementat(i) ).append( newline );
}
return buf.tostring();
}
}
//===================================================
public class book {
private string author;
private string title;
public book() {}
public void setauthor( string rhs ) { author = rhs; }
public void settitle( string rhs ) { title = rhs; }
public string tostring() {
return "book: author='" + author + "' title='" + title + "'";
}
}
//===================================================
import java.util.vector;
public class magazine {
private string name;
private vector articles;
public magazine() {
articles = new vector();
}
public void setname( string rhs ) { name = rhs; }
public void addarticle( article a ) {
articles.addelement( a );
}
public string tostring() {
stringbuffer buf = new stringbuffer( "magazine: name='" + name + "' ");
for( int i=0; i<articles.size(); i++ ){
buf.append( articles.elementat(i).tostring() );
}
return buf.tostring();
}
}
//===================================================
public class article {
private string headline;
private string page;
public article() {}
public void setheadline( string rhs ) { headline = rhs; }
public void setpage( string rhs ) { page = rhs; }
public string tostring() {
return "article: headline='" + headline + "' on page='" + page + "' ";
}
}
指定模式和规则
digester框架以模式(pattern)和规则(rule)为基础处理输入的xml。模式必须与xml元素匹配,包括其名字和在文档树内的位置。描述匹配模式的语法类似于xpath匹配模式,例如:catalog模式匹配顶层的<catalog>元素,catalog/book模式匹配直接嵌套在<catalog>元素内的<book>元素(但不匹配文档内其他位置的<book>元素)。
所有的模式都必须指定其完整名称——从根元素开始的完整路径。唯一的例外是包含通配符(“*”)的模式,例如*/name模式匹配xml文档内任何位置的<name>元素。但是根元素不必特别指出,因为所有的路径都是从根元素开始的绝对路径。
当digester发现一个指定的模式,它就执行关联的任务。由此可见,digester框架显然与sax解析器有着密切的关系(实际上,digester类实现了org.xml.sax.contenthandler,并维护着解析栈)。所有在digester中使用的规则必须扩展 org.apache.commons.digester.rule,后者本身提供了一些类似于sax的contenthandler回调函数的方法。例如,当遇到匹配元素的开始标记和结束标记时,begin()方法和end()方法将分别被调用。
一旦遇到匹配元素的内容,body()方法被调用;最后被调用的方法是finish(),这个方法在匹配元素的结束标记处理完毕之后被调用,用来执行可能需要的事后清理任务。然而,大多数时候我们不必关注这些方法,因为框架提供的标准规则很可能已经提供了所有必需的功能。
要反配制一个文档,首先创建一个org.apache.commons.digester.digester类的实例,如果必要的话,进行一些配置操作,指定必需的模式和规则,最后向parse()方法传递一个xml文件的引用。下面的digesterdriver示范了这一处理过程(必须在命令行上指定输入xml文档的名称)。
import org.apache.commons.digester.*;
import java.io.*;
import java.util.*;
public class digesterdriver {
public static void main( string[] args ) {
try {
digester digester = new digester();
digester.setvalidating( false );
digester.addobjectcreate( "catalog", catalog.class );
digester.addobjectcreate( "catalog/book", book.class );
digester.addbeanpropertysetter( "catalog/book/author", "author" );
digester.addbeanpropertysetter( "catalog/book/title", "title" );
digester.addsetnext( "catalog/book", "addbook" );
digester.addobjectcreate( "catalog/magazine", magazine.class );
digester.addbeanpropertysetter( "catalog/magazine/name", "name" );
digester.addobjectcreate( "catalog/magazine/article", article.class );
digester.addsetproperties( "catalog/magazine/article", "page", "page" );
digester.addbeanpropertysetter( "catalog/magazine/article/headline" );
digester.addsetnext( "catalog/magazine/article", "addarticle" );
digester.addsetnext( "catalog/magazine", "addmagazine" );
file input = new file( args[0] );
catalog c = (catalog)digester.parse( input );
system.out.println( c.tostring() );
} catch( exception exc ) {
exc.printstacktrace();
}
}
}
在上面的代码中,我们首先创建了digester类的一个实例digester,然后指定它不要用dtd验证xml文档的合法性——这是因为我们没有为xml文档定义dtd。接下来,我们指定了模式和关联的规则:objectcreaterule创建指定类的一个实例,并将它压入解析栈。 setpropertiesrule把bean属性设置成当前xml元素的属性值——规则的第一个参数是xml属性的名称,第二个参数是bean属性的名称。
setpropertiesrule获取的是xml属性的值,而beanpropertysetterrule获取的是位于当前元素内的原始字符数据值。使用 beanpropertysetterrule时不必指定要设置的bean属性名字,默认是当前xml元素的名称。在上面的例子中,在匹配 catalog/magazine/article/headline模式的规则定义中使用的就是默认值。最后,setnextrule弹出解析栈顶部的对象,并把该对象传递给它下面对象的指定名称的方法——通常用来把一个配置完毕的bean插入父对象。
注意,我们可以为同一个模式注册多个规则。如果注册了多个规则,则这些规则按照它们被加入到digester的次序执行,例如,如果要处理 catalog/magazine/article的元素,我们首先创建合适的article bean,然后设置page属性,最后弹出完成后的article bean,并把它插入magazine。
调用任意方法
我们不仅可以设置bean的属性,而且还可以调用堆栈内对象的任意方法。这通过callmethodrule完成,我们只需指定方法名字,如有必要,再说明调用的参数类型和数量。callparamrule用来定义传递给被调用函数的参数值,参数值可以从当前xml元素的命名的属性获取,也可以从当前元素包含的原始字符数据获取。例如,在前面实现digesterdriver的例子中,我们可以不用beanpropertysetterrule,而是通过显式调用属性的set方法达到同样的目的:
digester.addcallmethod( "catalog/book/author", "setauthor", 1 );
digester.addcallparam( "catalog/book/author", 0 );
上面的第一行代码给出了要调用的方法(即setauthor()),以及该调用需要的参数数量(即1)。第二行代码的意思是从元素包含的字符数据获取函数参数的值,把它作为参数数组的第一个传入(即索引是0的数组元素)。如果我们指定了xml元素属性的名称(例如 digester.addcallparam( "catalog/book/author", 0, "author" );),则参数值将从当前元素的相应属性值获取。
这里必须注意的是,“digester.addcallmethod( "pattern", "methodname", 0 );”这个语句不是指定了一个不带参数的方法调用,而是指定了带有一个参数的方法调用,它的值就是当前xml元素的字符数据!这样,我们又有了另一种替代 beanpropertysetterrule的办法:
digester.addcallmethod( "catalog/book/author", "setauthor", 0 );
如果要调用一个确实没有参数的方法,必须采用如下形式:digester.addcallmethod( "pattern", "methodname" );。
标准规则概要
下面简要说明所有标准规则。
创建
objectcreaterule:利用指定类的默认构造函数,创建该类的一个对象,并把对象压入栈。当元素处理结束时,对象被弹出。被实例化的类可通过class对象或类的全称给出。
factorycreaterule:利用指定的工厂类创建一个对象,把对象压入栈。对于没有提供默认构造函数的类,这一规则很有用。用于该规则的工厂类必须实现org.apache.commons.digester.objectcreationfactory接口。
设置属性
setpropertiesrule:利用指定名称的xml元素属性值,设置顶层bean的一个或者多个指定名称的属性。xml元素的属性名称和 bean的属性名称以string[]数组形式传入该规则(通常用来处理之类的结构)。
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
发表评论
-
Java对Json的工具类 JsonUtil 绿色版
2011-04-19 10:48 2435绿色版,无污染,无需下载第三方包.转自某某博客. packa ... -
模型是是搜索
2011-03-17 00:37 1128#!/usr/bin/env python # -*- co ... -
Java 调用浏览器访问指定URL. 多平台
2011-02-16 13:46 2904/////////////////////////////// ... -
Java Web 项目读取配置文件
2010-10-28 18:18 2848在开发过程中,我们经常会遇到读取配置文件的情况,对于配置文件的 ... -
j=j++与j=++j的区别
2010-09-21 16:28 1759jvm里面有两个存储区,一个是暂存区(是一个堆栈),另一个是变 ... -
JSON与JAVA数据的转换
2010-09-15 14:29 1001JSON与JAVA数据的转换 关键字: json java ... -
对web.xml 的几点配置心得。包括mime-mapping
2010-08-31 23:09 19371.指定了自己的javaEncoding (参考 http:/ ... -
JasperReports学习笔记
2010-08-30 13:03 1343reference: http://www.javaworl ... -
JFreeChart 教程二
2010-08-25 16:22 1138JFreeChart是一组功能强大、灵活易用的Java绘图AP ... -
JFreeChart 教程一
2010-08-25 16:20 999以下是需要画一个折线图查到的资料(放到这里备用): 原文地址 ... -
我和iText的第一次亲密接触
2010-08-19 22:58 1383要生成pdf文件,在网上查了下资料,首选iText,跟着大家走 ... -
引入多个Jar~
2010-08-19 13:49 551Zhe画 13:55:50 java命令引入jar时可以- ... -
Jetty7 Continuation 学习(一)
2010-08-19 08:44 1892Jetty7发布了,Jetty7支持servlet 2.5,且 ... -
jetty快速入门
2010-08-17 15:13 2823(0) Jetty 是一个开源的ser ... -
JNI(java 调用 本地接口)Tomcat的JNI库加载问题解决办法
2010-08-15 10:17 6714Tomcat的Release Notes 里有这么一段话: = ... -
Java入门--认识理解Java中native方法
2010-08-15 09:38 948Java不是完美的,Jav ... -
关于URL特殊符号的问题~
2010-08-14 15:20 1054HTML 格式编码的实用工具类。该类包含了将 String 转 ... -
InheritableThreadLocal 线程变量
2010-07-29 11:40 2287ThreadLocal有个缺陷,在子线程里无法访问父线程的变量 ... -
java基础补疑
2010-07-28 11:53 805java语言的关键字,变量修饰符,如果用transient声明 ... -
转自Javaeye论坛~作者
2010-07-28 09:53 923只身在他乡,常常想起我的父亲,在我们当地他是出名的木匠师傅,一 ...
相关推荐
### Digester组件简化XML文件处理操作 #### 一、引言 随着Web技术的发展,XML作为数据交换格式的重要性日益凸显。然而,对于大型且复杂的XML文档进行解析与处理时,传统的方法如DOM(Document Object Model)和SAX...
标题“利用commons-digester解析XML”涉及到的是Java开发中的一种处理XML文档的工具——Apache Commons Digester。这个库提供了一种方便的方式来映射XML文档结构到Java对象,从而简化了XML数据的处理过程。 Apache ...
Digester能够根据定义好的规则自动将XML文档转换成Java对象,非常适合用在配置文件读取、数据交换等场景。 #### 二、Digester的基本原理 1. **SAX事件驱动**:Digester内部使用SAX事件模型来解析XML文档。当解析器...
然而,处理XML文件并非易事,这就引入了Apache Commons Digester库,它提供了一种方便的方式来将XML文档的结构映射到Java对象的层次结构上。本文将深入探讨如何使用Digester解析XML文件,以及在实际项目中如何应用。...
Digester的使用基于一系列预定义或自定义的规则,这些规则决定了XML文档的元素与Java对象之间的映射关系。当解析XML时,它会按照这些规则触发相应的Java代码执行,简化了从XML到业务逻辑的转换过程。学习 Digester,...
总之,Apache Digester 提供了一个强大且灵活的框架,用于简化XML文档到Java对象的映射过程。通过定义和组织一系列规则,开发者可以轻松地从XML配置文件中提取数据,并将其转换为易于操作的对象模型。这在许多需要...
Java反射和Digester库是Java开发中的两个重要概念,它们在处理动态代码执行和XML文档解析方面发挥着关键作用。 **Java反射** 是Java语言的一个强大特性,它允许程序在运行时检查和操作类、接口、方法和字段。通过...
总之,Apache Commons Digester是一个强大的工具,它简化了XML文档到Java对象的映射,使得在Java应用中处理XML数据变得更加便捷。结合 Commons Logging 和 Commons BeanUtils,可以实现更高效、灵活的XML解析和数据...
**Digester** 是Apache Commons项目中的一个子项目,主要用于简化XML文档的解析工作。它建立在SAX的基础之上,通过定义一系列的模式(Pattern)和规则(Rule),能够有效地处理复杂的XML结构,从而简化开发者的编程...
值得注意的是,为了确保配置文件能够被正确地解析,XML文档配置文件必须使用DTD(Document Type Definition,文档类型定义),而DTD正是`xmlrules`包的一部分。 #### Digester与XML规则文件 在实际应用中,我们...
Apache Commons Digester是一个用于将XML数据映射到Java对象的工具,主要应用于处理XML配置文件或数据文件。它通过定义一系列的模式和规则,能够自动地创建和填充Java对象的结构,大大简化了XML解析的过程。 ...
- **XML解析**:Digester使用JAXP (Java API for XML Processing) 来解析XML文档,提取出元素和属性信息。 - **规则设定**:开发者可以通过`addRule`方法设置规则,例如当遇到特定的XML元素时,执行相应的Java方法...
为此,Apache Commons项目提供了Digester组件,它能够简化XML到Java对象的转换过程。 #### Digester简介 Digester是Apache Commons项目下的一个子项目,其主要功能是从XML文档中创建Java Bean实例。通过一系列简单...
7. **处理命名空间(Namespaces)**: Digester 支持处理XML文档中的命名空间。通过 `setNamespaceAware(true)` 开启命名空间处理,然后使用带有命名空间前缀的XPath表达式来匹配规则。 8. **错误处理和调试**: ...
通过定义一系列的“消化规则”(Rule),我们可以指定当XML文档的某个元素出现时,应该执行什么操作,比如创建新的Java对象、设置对象属性或者调用对象方法。 `rule.xml`文件是配置 Digester 的核心,它定义了针对...
在IT行业中,XML(eXtensible Markup Language)是一种用于存储和传输数据的标准化格式,特别是在Web服务和配置文件中...在实际项目中,正确地配置和使用Digester可以极大地简化XML处理的工作,提高代码的可维护性。
本文将深入探讨如何使用Apache的 Digester 库来解析XML文档,这是一款强大的工具,能够将XML数据映射到Java对象,简化了处理XML的过程。 Digester 是Apache Commons项目的一部分,它提供了一种规则驱动的方法来处理...
`Digester`使用DOM4J来读取和处理XML文档。 3. `commons-beanutils-1.8.0.jar`: Apache Commons BeanUtils库简化了JavaBeans的使用,提供了一些便捷的方法来操作对象的属性。`Digester`利用BeanUtils来反射调用Java...