Digester 详细介绍 : apache common digester ,这里描述一个常见问题的解决方案
问题:
Digester 作为 SAX 解析 xml 的实现,它的原理就是制定一些规则,在遍历每个节点时检查是否有匹配的规则,如果有就执行对应的操作 。
比如:
InputStream is = new FileInputStream(file); Digester digester = new Digester(); digester.push(this); digester.setValidating(false); digester.addObjectCreate("level1", Level1.class); digester.addBeanPropertySetter("level1/property","property"); digester.addSetNext("level1","register"); digester.parse(is);
这段代码即遇见level1标签就就新建 Level1 实例对象 L,并把 property 子标签的标签值付给 L 对象的 property 属性。这里就遇到了空格问题,如果property 子标签中前后有空白,可以实验得到 L对象的property属性是trim过后的值,如果想要保留空白呢?
分析:
由于 digester 的一个动作对应一个rule,则看一下 addBeanPropertySetter 的实现:
public void addBeanPropertySetter(String pattern, String propertyName) { addRule(pattern,new BeanPropertySetterRule(propertyName)); }
那么可以看一下 BeanPropertySetterRule 的实现 ,首先知道 rule 通过其 body 方法来得到标签内的字符串值,则可以看一下 body 方法 :
/** * Process the body text of this element. * * @param namespace the namespace URI of the matching element, or an * empty string if the parser is not namespace aware or the element has * no namespace * @param name the local name if the parser is namespace aware, or just * the element name otherwise * @param text The text of the body of this element */ public void body(String namespace, String name, String text) throws Exception { // log some debugging information if (digester.log.isDebugEnabled()) { digester.log.debug("[BeanPropertySetterRule]{" + digester.match + "} Called with text '" + text + "'"); } bodyText = text.trim() }
可见,由 rule 获得 标签值是已经 trim 过的,当然就没有办法了么?
解决:
自定义rule
由于系统自带的所有rule都是继承自 rule ,而实现一些公共接口,而现在要求和 BeanPropertySetterRule 没什么区别,只不过要求 body 方法不要对值进行 trim,则可以自己写个rule :
public class BeanPropertySetterRuleWhiteSpace extends Rule { //......省略 public void body(String namespace, String name, String text) throws Exception { //不要 trim bodyText = text; } }
那么根据 addBeanPropertySetter 的调用,可以这样子写了 :
digester.addBeanPropertySetter("level1/property","property");
==
digester.addRule("level1/property",new BeanPropertySetterRuleWhiteSpace("property"));
则最终解析得到的 Level1 实例的 property 属性前后空格得以保存。