http://commons.apache.org/proper/commons-digester/guide/binder.html
You configure the Digester by implementingRulesModule. You passDigesterLoadera module,theDigesterLoaderpasses your module aRulesBinder,and your module uses the binder to configurepatterns/rulesbindings. A binding most commonly consist of a mapping between a pattern and one or moreRule. For example:
class EmployeeModule implements RulesModule { protected void configure( RulesBinder rulesBinder ) { rulesBinder.forPattern( "employee" ).createObject().ofTypeEmployee.class ); rulesBinder"employee/firstName" ).setBeanProperty(); rulesBinder"employee/lastName" (); rulesBinder"employee/address" ) .createObjectAddressthen() .setNext"addAddress" "employee/address/type" "employee/address/city" "employee/address/state" (); } }
DRY (Don't Repeat Yourself): Repeating "rulesBinder" over and over for each binding can get a little tedious. The Digester package provides a module support class namedAbstractRulesModulewhich implicitly gives you access toRulesBinder's methods. For example,we could extendAbstractRulesModuleand rewrite the above binding as:
http://commons.apache.org/proper/commons-digester/guide/plugins.html
An Example
Let's start off with an example.
Given the following digester rules in the main "parsing" application:
the following input can be processed:
http://commons.apache.org/proper/commons-digester/guide/core.html
Processing Rules
Theprevious sectiondocumented how you identifywhenyou wish to have certain actions take place. The purpose of processing rules is to definewhatshould happen when the patterns are matched.
Formally,a processing rule is a Java class that subclasses theorg.apache.commons.digester3.Ruleinterface. Each Rule implements one or more of the following event methods that are called at well-defined times when the matching patterns corresponding to this rule trigger it:
- begin()- Called when the beginning of the matched XML element is encountered. A data structure containing all of the attributes corresponding to this element are passed as well.
- body()- Called when nested content (that is not itself XML elements) of the matched element is encountered. Any leading or trailing whitespace will have been removed as part of the parsing process.
- end()- Called when the ending of the matched XML element is encountered. If nested XML elements that matched other processing rules was included in the body of this element,the appropriate processing rules for the matched rules will have already been completed before this method is called.
- finish()- Called when the parse has been completed,to give each rule a chance to clean up any temporary data they might have created and cached.
As you are configuring your digester,you can call theaddRule()method to register a specific element matching pattern,along with an instance of aRuleclass that will have its event handling methods called at the appropriate times,as described above. This mechanism allows you to createRuleimplementation classes dynamically,to implement any desired application specific functionality.
In addition,a set of processing rule implementation classes are provided,which deal with many common programming scenarios. These classes include the following:
- ObjectCreateRule- When thebegin()method is called,this rule instantiates a new instance of a specified Java class,and pushes it on the stack. The class name to be used is defaulted according to a parameter passed to this rule's constructor,but can optionally be overridden by a classname passed via the specified attribute to the XML element being processed. When theend()method is called,the top object on the stack (presumably,the one we added in thebegin()method) will be popped,and any reference to it (within the Digester) will be discarded.
- FactoryCreateRule- A variation ofObjectCreateRulethat is useful when the Java class with which you wish to create an object instance does not have a no-arguments constructor,or where you wish to perform other setup processing before the object is handed over to the Digester.
- SetPropertiesRule- When thebegin()method is called,the digester uses the standard Java Reflection API to identify any JavaBeans property setter methods (on the object at the top of the digester's stack) who have property names that match the attributes specified on this XML element,and then call them individually,passing the corresponding attribute values. These natural mappings can be overridden. This allows (for example) aclassattribute to be mapped correctly. It is recommended that this feature should not be overused - in most cases,it's better to use the standardBeanInfomechanism. A very common idiom is to define an object create rule,followed by a set properties rule,with the same element matching pattern. This causes the creation of a new Java object,followed by "configuration" of that object's properties based on the attributes of the same XML element that created this object.
- SetPropertyRule- When thebegin()method is called,the digester calls a specified property setter (where the property itself is named by an attribute) with a specified value (where the value is named by another attribute),on the object at the top of the digester's stack. This is useful when your XML file conforms to a particular DTD,and you wish to configure a particular property that does not have a corresponding attribute in the DTD.
- SetNextRule- When theend()method is called,the digester analyzes the next-to-top element on the stack,looking for a property setter method for a specified property. It then calls this method,passing the object at the top of the stack as an argument. This rule is commonly used to establish one-to-many relationships between the two objects,with the method name commonly being something like "addChild".
- SetTopRule- When theend()method is called,the digester analyzes the top element on the stack,passing the next-to-top object on the stack as an argument. This rule would be used as an alternative to a SetNextRule,with a typical method name "setParent",if the API supported by your object classes prefers this approach.
- CallMethodRule- This rule sets up a method call to a named method of the top object on the digester's stack,which will actually take place when theend()method is called. You configure this rule by specifying the name of the method to be called,the number of arguments it takes,and (optionally) the Java class name(s) defining the type(s) of the method's arguments. The actual parameter values,if any,will typically be accumulated from the body content of nested elements within the element that triggered this rule,using the CallParamRule discussed next.
- CallParamRule- This rule identifies the source of a particular numbered (zero-relative) parameter for a CallMethodRule within which we are nested. You can specify that the parameter value be taken from a particular named attribute,or from the nested body content of this element.
- NodeCreateRule- A specialized rule that converts part of the tree into aDOM Nodeand then pushes it onto the stack.
You can create instances of the standardRuleclasses and register them by callingdigester.addRule(),as described above. However,because their usage is so common,shorthand registration methods are defined for each of the standard rules,directly on theDigesterclass. For example,the following code sequence: