您的位置:首页 > 其它

Digester(xml解析工具)

2015-01-10 19:38 316 查看

Digester学习

下面部分摘要与百度百科

Digester底层采用SAX解析XML文件,所以很自然的,对象转换由"事件"驱动,即在识别出特定XML元素时(实际被细分为begin、body、end、finish四个时点),将执行特定的动作,比如创建特定的Java对象,或调用特定对象的方法等。此处的XML元素根据匹配模式(matching pattern)识别,而相关操作由规则(rule)定义。在转换过程中,Digester维持了一个对象栈,可以看作对象转换的工作台,用来存放转换中生成的、或是为转换临时创建的Java对象。对输入XML文件作了一趟完整的扫描后,对象栈的栈顶元素即为目标对象。由于Digester屏蔽了SAX解析的细节,使用者仅需关注转换操作本身,大大简化了转换操作。



对使用者而言,Digester的核心在于匹配模式与规则(matching pattern + rule)

模式匹配(pattern)

<a> -- Matches pattern "a"

<b>-- Matches pattern "a/b"

<c/>-- Matches pattern "a/b/c"

<c/>-- Matches pattern "a/b/c"

</b>

<b>-- Matches pattern "a/b"

<c/>-- Matches pattern "a/b/c"

<c/>-- Matches pattern "a/b/c"

<c/>-- Matches pattern "a/b/c"

</b>

</a>



规则(rule)

1. 对象创建ObjectCreateRule:当begin()方法被调用时, 此rule创建相应Java对象, 并将其push到Digester的对象栈上。当end()方法被调用时, 栈顶对象将被pop,Digester内所有对该对象的引用都将失效。

例如:

digester.addObjectCreate("Server","org.apache.catalina.core.StandardServer","className");

第一个参数为xml元素,第二参数为要创建的对象类,第三个参数为如果这个xml元素中配置了这个className属性,则用这个className代替第二个参数.

当SAX解析XML到<Serverport="8005" shutdown="SHUTDOWN">元素时,begin事件触发,

创建StandardServer对象,如果xml的server元素定义了className属性,则将用这个className代替org.apache.catalina.core.StandardServer,创建对象。

2. 属性赋值SetPropertiesRule 当begin()方法被调用时,Digester使用标准的Java反射API,将栈顶对象的属性设置为XML元素的同名属性值。

例如:

digester.addSetProperties("Server");

当SAX解析XML到<Server port="8005" shutdown="SHUTDOWN">元素时,begin事件触发,得到xml中server元素的属性port和shutdown,根据属性名反射设置栈顶对象(StandardServer)的属性,这个StandardServer对象有setPort和setShutdown方法。

3. 父子关系管理 SetNextRule当end()方法被调用时,Digester将栈顶元素设置进次栈顶元素中(调用相应的设置方法)。

例如:

digester.addSetNext("Server","setServer","org.apache.catalina.Server");

第一个参数为xml元素,第二个为当前栈对象的父栈对象的方法名,第三个参数是否方法参数类型。

如果在调用digester.parse(inputSource)前调用digester.push(catalina);方法压人栈顶对象,那么这个前两个语句执行后,实例化并赋值属性的StandardServer对象(当前栈对象),在执行第三个语句时,调用父栈对象catalina的setServer(org.apache.catalina.Server)方法,完成子对象实例到父对象属性的赋值。



规则实现

继承自org.apache.tomcat.util.digester.Rule,例如:

这里实现了begin事件,例如:参数name为/Server/Service/Engine/Host,那么digester.peek(0)得到Host栈对象,digester.peek(1)得到Engine栈对象,这里是有层次关系的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: