Specifying Patterns and Rules
The Digester class processes the input XML document based on patterns and rules. The patterns must match XML elements, based on their name and location in the document tree. The syntax used to describe the matching patterns resembles the XPath match patterns, a little: the pattern catalog matches the top-level <catalog> element, the pattern catalog/book matches a <book> element nested directly inside a <catalog> element, but nowhere else in the document, etc.
All patterns are absolute: the entire path from the root element on down has to be specified. The only exception are patterns containing the wildcard operator *: the pattern */name will match a <name> element anywhere in the document. Also note that there is no need for a special designation for the root element, since all paths are absolute.
Whenever the Digester encounters one of the specified patterns, it performs the actions that have been associated with it. In this, the Digester framework is of course related to a SAX parser (and in fact, the Digester class implements org.xml.sax.ContentHandler and maintains the parse stack). All rules to be used with the Digester must extend org.apache.commons.digester.Rule -- which in itself exposes methods similar to the SAX ContentHandler callbacks: begin() and end() are called when the opening and closing tags of the matched element are encountered.
The body() method is called for the content nested inside of the matched element, and finally, there is a finish() method, which is called once processing of the closing tag is complete, to provide a hook to do possible final clean-up chores. Most application developers will not have to concern themselves with these functions, however, since the standard rules that ship with the framework are likely to provide all desired functionality.
To unmarshal a document, then, create an instance of the org.apache.commons.digester.Digester class, configure it if necessary, specify the required patterns and rules, and finally, pass a reference to the XML file to the parse() method. This is demonstrated in the DigesterDriver class below. (The filename of the input XML document must be specified on the command line.)
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();
}
}
}
After instantiating the Digester, we specify that it should not validate the XML document against a DTD -- because we did not define one for our simple Catalog document. Then we specify the patterns and the associated rules: the ObjectCreateRule creates an instance of the specified class and pushes it onto the parse stack. The SetPropertiesRule sets a bean property to the value of an XML attribute of the current element -- the first argument to the rule is the name of the attribute, the second, the name of the property.
Whereas SetPropertiesRule takes the value from an attribute, BeanPropertySetterRule takes the value from the raw character data nested inside of the current element. It is not necessary to specify the name of the property to set when using BeanPropertySetterRule: it defaults to the name of the current XML element. In the example above, this default is being used in the rule definition matching the catalog/magazine/article/headline pattern. Finally, the SetNextRule pops the object on top of the parse stack and passes it to the named method on the object below it -- it is commonly used to insert a finished bean into its parent.
Note that it is possible to register several rules for the same pattern. If this occurs, the rules are executed in the order in which they are added to the Digester -- for instance, to deal with the <article> element, found at catalog/magazine/article, we first create the appropriate article bean, then set the page property, and finally pop the completed article bean and insert it into its magazine parent.
Invoking Arbitrary Functions
It is not only possible to set bean properties, but to invoke arbitrary methods on objects in the stack. This is accomplished using the CallMethodRule to specify the method name and, optionally, the number and type of arguments passed to it. Subsequent specifications of the CallParamRule define the parameter values to be passed to the invoked functions. The values can be taken either from named attributes of the current XML element, or from the raw character data contained by the current element. For instance, rather than using the BeanPropertySetterRule in the DigesterDriver implementation above, we could have achieved the same effect by calling the property setter explicitly, and passing the data as parameter:
digester.addCallMethod( "catalog/book/author", "setAuthor", 1 );
digester.addCallParam( "catalog/book/author", 0 );
The first line gives the name of the method to call (setAuthor()), and the expected number of parameters (1). The second line says to take the value of the function parameter from the character data contained in the <author> element and pass it as first element in the array of arguments (i.e., the array element with index 0). Had we also specified an attribute name (e.g., digester.addCallParam( "catalog/book/author", 0, "author" );), the value would have been taken from the respective attribute of the current element instead.
One important caveat: confusingly, digester.addCallMethod( "pattern", "methodName", 0 ); does not specify a call to a method taking no arguments -- instead, it specifies a call to a method taking one argument, the value of which is taken from the character data of the current XML element! We therefore have yet another way to implement a replacement for BeanPropertySetterRule:
digester.addCallMethod( "catalog/book/author", "setAuthor", 0 );
To call a method that truly takes no parameters, use digester.addCallMethod( "pattern", "methodName" );.
分享到:
相关推荐
2. **初始化 Stack**:使用 `Digester.push()` 方法将一个初始对象放入 Digester 的 Stack 中。这个初始对象在整个解析过程中将起到桥梁的作用,使得最终可以访问到解析得到的对象。 3. **注册匹配模式和规则**:...
它被称为 django_tastypie_digester 因为它消化了 django_tastypie 提要。 用法 客户端初始化 In [1]: from django_tastypie_digester import Api In [2]: api = Api('http://127.0.0.1:8000/api/v1/') In [3]: ...
2. 配置`Digester`属性,例如设置是否验证XML文档。 3. 添加处理规则,这些规则定义了当解析到特定的XML节点时应执行的操作,如创建对象、设置属性、建立对象间的关联等。 4. 调用`digester.parse()`方法,传入XML...
2. **模式匹配**:规则基于XPath表达式或者更简单的“路径”来匹配XML元素。例如,`/users/user`表示用户列表中的每个用户元素。通过这种方式,Digester可以定位到XML文档中的特定部分。 3. **类工厂与对象创建**:...
2. **规则设置**: 定义一系列规则,每个规则通常包括一个模式(对应XML文档的路径)和一个动作(当模式匹配时执行的操作,如创建对象、设置属性等)。 3. **解析XML**: 使用`parse()`方法读取XML文件并执行规则链。...
2. **解析XML**:使用`Digester`解析XML文档,并根据设定的规则执行操作。 下面是一个基本的Digester实例: ```java import org.apache.commons.digester.Digester; import org.xml.sax.SAXException; // 假设有...
2. **规则(Rules)**: 规则是 Digester 的核心,它们定义了XML元素如何映射到Java对象。有多种类型的规则,如 `CallMethodRule` 调用对象的方法,`CreateObjectRule` 创建新对象,`SetPropertiesRule` 设置对象属性...
赠送jar包:commons-digester3-3.2.jar; 赠送原API文档:commons-digester3-3.2-javadoc.jar; 赠送源代码:commons-digester3-3.2-sources.jar; 赠送Maven依赖信息文件:commons-digester3-3.2.pom; 包含翻译后...
2. **RuleSet**: RuleSet是一组相关的Rule,它们共同作用于特定的XML结构。它允许你组织和管理一组相关的解析规则,使得代码更加模块化和可重用。`org.apache.commons.digester.RuleSet`是RuleSet的接口,你在运行时...
2. **缺失依赖**:`commons-digester-2.1.jar`可能依赖于其他Apache Commons库,如`commons-beanutils`、`commons-collections`等,如果没有正确引入,可能会引发运行时错误。 3. **API变更**:如果你的代码是基于较...
**2. 使用流程** 使用Digester通常包括以下步骤: - **创建Digester实例**:首先需要创建一个Digester对象,它是整个解析过程的管理者。 - **添加规则**:然后根据XML结构,添加一系列Rule,这些规则定义了如何...
2. **创建Digester实例**:然后,创建一个`Digester`对象,它是整个解析过程的控制器。 3. **定义规则**:使用`addRule`或`addSetProperties`等方法定义规则,将XML元素与Java对象的方法或属性关联起来。例如,`add...
2. **安装与引入** 要使用Digester,首先需要将其依赖添加到项目中。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```xml <groupId>commons-digester <artifactId>commons-digester <version>3.2...
2. 独立的规则文件: 为了解决硬编码规则的可读性和可维护性问题,Digester还支持从外部XML文件加载规则。这种方式将解析逻辑与业务逻辑分离,使得代码更清晰,易于维护。规则文件通常采用DOSCH(Digester Object ...
##### 2. 模式匹配 - Digester通过匹配模式来定位XML文件中的元素。模式匹配是一种灵活的方式来确定要处理的元素。例如,在上面给出的示例XML文件中,可以通过定义如下模式来定位学生信息: - `<students>`: 匹配...
2. `Parent.java`:代表XML的`parent`元素。 3. `Child.java`:代表XML的`child`元素。 4. `Grandchild.java`:代表XML的`grandchild`元素。 接下来,我们需要编写 Digester配置代码,为每种元素设置相应的规则。这...
本文将深入探讨如何使用Apache的 Digester 库来解析XML文档,这是一款强大的工具,能够将XML数据映射到Java对象,简化了处理XML的过程。 Digester 是Apache Commons项目的一部分,它提供了一种规则驱动的方法来处理...
2. **注册 RuleSet**:根据业务需求,向Digester实例添加适当的RuleSet,这些RuleSet包含了处理XML数据的规则集合。 3. **绑定规则**:定义XML元素到Java对象的映射,这通常通过`addRule`或`addRuleSet`方法完成。 4...
赠送jar包:commons-digester3-3.2.jar; 赠送原API文档:commons-digester3-3.2-javadoc.jar; 赠送源代码:commons-digester3-3.2-sources.jar; 赠送Maven依赖信息文件:commons-digester3-3.2.pom; 包含翻译后...