您的位置:首页 > 其它

commons-digester解析xml

2015-06-30 16:02 453 查看
http://commons.apache.org/proper/commons-digester/guide/binder.html

You configure the Digester by implementing RulesModule.
You pass DigesterLoader a module, the DigesterLoader passes your module a RulesBinder,
and your module uses the binder to configure patterns/rules bindings. A binding most commonly consist of a mapping between a pattern and one or more Rule.
For example:

class EmployeeModule
implements RulesModule
{

protected void configure( RulesBinder rulesBinder )
{
rulesBinder.forPattern( "employee" ).createObject().ofType( Employee.class );
rulesBinder.forPattern( "employee/firstName" ).setBeanProperty();
rulesBinder.forPattern( "employee/lastName" ).setBeanProperty();

rulesBinder.forPattern( "employee/address" )
.createObject().ofType( Address.class )
.then()
.setNext( "addAddress" );
rulesBinder.forPattern( "employee/address/type" ).setBeanProperty();
rulesBinder.forPattern( "employee/address/city" ).setBeanProperty();
rulesBinder.forPattern( "employee/address/state" ).setBeanProperty();
}

}


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 named AbstractRulesModule which
implicitly gives you access to RulesBinder's methods. For example, we could extend AbstractRulesModule and rewrite the above binding as:

class EmployeeModule
extends AbstractRulesModule
{

@Override
protected void configure()
{
forPattern( "employee" ).createObject().ofType( Employee.class );
forPattern( "employee/firstName" ).setBeanProperty();
forPattern( "employee/lastName" ).setBeanProperty();

forPattern( "employee/address" )
.createObject().ofType( Address.class )
.then()
.setNext( "addAddress" );
forPattern( "employee/address/type" ).setBeanProperty();
forPattern( "employee/address/city" ).setBeanProperty();
forPattern( "employee/address/state" ).setBeanProperty();
}

}


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:

Digester digester = new Digester();
PluginRules rc = new PluginRules();
digester.setRules( rc );

digester.addObjectCreate( "pipeline", Pipeline.class );

digester.addCallMethod( "pipeline/source", "setSource", 1 );
digester.addCallParam( "pipeline/source", 0, "file" );

PluginCreateRule pcr = new PluginCreateRule( Transform.class );
digester.addRule( "pipeline/transform", pcr );
digester.addSetNext( "pipeline/transform", "setTransform" );

digester.addCallMethod("pipeline/destination", "setDest", 1);
digester.addCallParam("pipeline/destination", 0, "file");

digester.parse( filename );


the following input can be processed:

<pipeline>
<source file="input.txt"/>
<transform plugin-class="SubstituteTransform">
<from>changeme</from>
<to>changed</to>
</transform>
<destination file="output.txt"/>
</pipeline>


http://commons.apache.org/proper/commons-digester/guide/core.html


Processing Rules

The previous section documented how you identify when you wish to have certain actions take place. The purpose
of processing rules is to define what should happen when the patterns are matched.

Formally, a processing rule is a Java class that subclasses the org.apache.commons.digester3.Rule interface.
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 the addRule() method to register a specific element matching pattern, along with an instance of a Rule class that will have its event handling methods called at the appropriate times, as described
above. This mechanism allows you to create Rule implementation 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 the begin() 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 the end() method is called, the top object on the stack (presumably, the one we added in the begin() method) will be popped, and any reference to it (within the Digester) will be discarded.
FactoryCreateRule - A variation of ObjectCreateRule that 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 the begin() 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) a class attribute to be mapped correctly. It is recommended that this feature should not be overused - in most cases, it's better to use the standard BeanInfo mechanism.
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 the begin() 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 the end() 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 the end() method is called, the digester analyzes the top element
on the stack, looking for a property setter method for a specified property. It then calls this method, 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 the end() 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 a DOM Node and
then pushes it onto the stack.

You can create instances of the standard Rule classes and register them by calling digester.addRule(), as described above. However, because their usage is so common, shorthand registration methods are defined for each of the standard rules,
directly on the Digester class. For example, the following code sequence:

Rule rule = new SetNextRule( digester, "addChild",
"com.mycompany.mypackage.MyChildClass" );
digester.addRule( "a/b/c", rule );


can be replaced by:

digester.addSetNext( "a/b/c", "addChild",
"com.mycompany.mypackage.MyChildClass" );
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: