Digester 空白保留问题

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 属性前后空格得以保存。


 

你可能感兴趣的:(apache,xml)