当前位置: 首页 > news >正文

Digester学习笔记(三)转载

总觉得,Digester不仅仅能作配置文件解析,而且可以作得更多。

 

配置属性

  Digester用来解析应用系统的配置文件,其本身也有很可配置的属性。

属性描述
classLoader指定类装载器(class loader)。ObjectCreateRule 和 FactoryCreateRule两个规则中,需要动态加载一些类(如那些盛放XML解析出来的数据的javaBean等),装载器可以在次指定。如果不指定,对这此类的加载将会利用线程上下文中的加载器(当useContextClassLoader值为真时)或利用加载Digester的那个加载器。
errorHandler指定 SAX ErrorHandler,以在出现此类错误时调用。默认情况下,任何解析错误都会被记入日志,Digest会继续进行解析。
namespaceAware一个布尔值,为真时对XML文件的解析时会考虑元素的域名空间(如不同的域名空间的同名元素会视为不同的元素)
ruleNamespaceURI指定后续加入的规则所属的命名空间,如果此值为null,则加入的规则不与任何命名空间相联系。
rules设定规则模板与XML元素的匹配处理程序。由于这个匹配程序是插件式的,所以匹配工作的完成可以用用户定义的匹配程序未完成。默认情况下,使用Digester提供的匹配器。
useContextClassLoader一个布尔值,为真时FactoryCreateRule 和 ObjectCreateRule 两个规则中对类的装载将会采用当前线程上下文中指定的加载器。默认情况下,对类的动态加载会利用加载Digester的那个装载器。
validating一个布尔值,为真时解析器会根据DTD内容对XML文档进行合法性检查,默认值是假,解析器只是检查XML是否格式良好(well formed).


  除了上述属性外,还可以注册一个本地DTD,以供DOCTYPE声明引用。这样的注册告诉XML解析器,当遇到DOCTYPE声明时,应使用刚注册的DTD的内容,而不是DOCTYPE声明中的标识符(identifier)。
  例如,Struect框架控制器中,使用下述的注册,告诉Structs使用一个本地的DTD中的相关内容来处理Structs配置文件,这样可以适用于那些没有连接到互联网的应用环境,而在连到互联网的环境中可以加快运行速度(因为它避免了通过网络去取相关的资源)。

URL url = new URL("/org/apache/struts/resources/struts-config_1_0.dtd");
digester.register("-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",url.toString());

规则集打包


  通常情况下,一个规则被创建后,接着便注册,然后等在event时被调用,这些规则集很难为其它应用程序直接复用。一个解决方法是将所有规则都放在一个类中,此由这些规则可以很简单地被装载然后被注册使用。RuleSet接口就是为些而设计,一般是通过扩展RuleSetBase类来开发规则集类。如例:
public class MyRuleSet extends RuleSetBase {
  public MyRuleSet() {
    this("");
  }
  public MyRuleSet(String prefix) {
    super();
    this.prefix = prefix;
    this.namespaceURI = "http://www.mycompany.com/MyNamespace";
  }
  protected String prefix = null;
  public void addRuleInstances(Digester digester) {
    digester.addObjectCreate(prefix + "foo/bar",
      "com.mycompany.MyFoo");
    digester.addSetProperties(prefix + "foo/bar");
  }
}
可以这样使用这个规则集
Digester digester = new Digester();
... 一些配置Digester ...
digester.addRuleSet(new MyRuleSet("baz/"));

带命名空间的XML解析


  这种情况下,使用Digester的步骤为:
  1. 在Digester初始化部分,指明要考虑命名空间。
    digester.setNamespaceAware(true);
  2. 指明一些规则的命名空间,如
    digester.setRuleNamespaceURI("http://www.mycompany.com/MyNamespace");
  3. 接下来定义一些与此命名空间有关的规则,此时可以省却前缀,如
    digester.addObjectCreate("foo/bar", "com.mycompany.MyFoo");
    digester.addSetProperties("foo/bar");
  4. 对其它命名空间,重复前面的2步

  另外,在指明要digester考虑命名空间之后,在定义匹配模板时,可以将命名空间别名加“:”作为元素名称的一部分使用。这与无命名空间时是一致的。

开发定制的匹配处理过程


  通过实现 org.apache.commons.digester.Rules接口或扩展org.apache.commons.digester.RulesBase类来达到定制匹配过程的目的。
  Digester提供ExtendedBaseRules来扩展了匹配模板的定义,引入了特殊通配字符?和*以及!,提供RegexRules来支持以正则式的语法定义匹配模板,提供WithDefaultsRulesWrapper来支持默认规则(即其它规则都不匹配时的处理规则)。

一些认识


  通过看说明材料,尤其在学习Digester包中的Catalog例子以后,有一些认识:
  1、由于xml对属性名字的定义要求,与Java中对方法名字的定义要求不一致,导致出现不能自动映射的情况,如year-made标签属性,就不可能有方法setYear-made;
  2、对于根元素,与其子元素建立联系,有几种办法:一种是先生成根元素实例,压入栈,然后解析,将调用方法规则建立联系;另一种是解析的过程中第一个创建它,然后用getRoot的方法得到。
  3、如果某对象类构造都要参数,则此时需要扩展AbstractObjectCreationFactory类为这种对象建立一个Factory,在这个Factory中取得初始化参数值然后再创建一个对象实例。
  4、设有某个标签,要想自动用该标签子元素的内容填充该标签对应的对象的属性,则需要用digester.setRules(new ExtendedBaseRules()),然后addRules(),然后再调用addBeanPropertySetter("bala/lala/?");进行规则定义,注意此模板中有通配符。
  5、如果对象的属性是整型,则Digester自动将xml文件中字符串值转换为整型。
  6、在指明要digester考虑命名空间之后,如果不会引起歧义,完全可以忽略命名空间的存在,除非你要针对特定的命名空间进行特定的处理。

相关文章:

  • 【C语言】09条件编译
  • c# winform项目用到的部分知识点总结
  • Intellij IDEA 快捷键整理(TonyCody)
  • C optimization tutorial 翻译 C语言优化教程(一)
  • eclipse 的代码着色插件 --Eclipse Color Theme
  • CentOS上yum安装nginx+mysql+php+php-fastcgi
  • 精简操作系统Linux
  • UVa 10827 - Maximum sum on a torus
  • 九大CTO畅谈软件定义未来
  • 磁盘被写保护
  • Eclipse can not find the tag library descriptor for http://java.sun.com/jsf/*
  • 【AaronYang风格】第一篇 CodeFirst 初恋
  • 想看,该看,需要看的书。。。。。。
  • Android之HttpPost与HttpGet使用
  • Linux下基于POSIX标准的共享内存操作示例
  • JAVA_NIO系列——Channel和Buffer详解
  • Java编程基础24——递归练习
  • java中的hashCode
  • laravel 用artisan创建自己的模板
  • Octave 入门
  • PHP的类修饰符与访问修饰符
  • tweak 支持第三方库
  • Vue 重置组件到初始状态
  • Vue全家桶实现一个Web App
  • 闭包--闭包作用之保存(一)
  • 京东美团研发面经
  • 消息队列系列二(IOT中消息队列的应用)
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ​低代码平台的核心价值与优势
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #LLM入门|Prompt#3.3_存储_Memory
  • (Git) gitignore基础使用
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (第61天)多租户架构(CDB/PDB)
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (轉)JSON.stringify 语法实例讲解
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .NET DataGridView数据绑定说明
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .net下简单快捷的数值高低位切换
  • @AutoConfigurationPackage的使用
  • [AUTOSAR][诊断管理][ECU][$37] 请求退出传输。终止数据传输的(上传/下载)
  • [BUUCTF]-PWN:wustctf2020_number_game解析(补码,整数漏洞)
  • [C#]C# OpenVINO部署yolov8图像分类模型
  • [C#]winform制作仪表盘好用的表盘控件和使用方法
  • [C++]运行时,如何确保一个对象是只读的
  • [Codeforces] probabilities (R1600) Part.1
  • [EWS]查找 文件夹
  • [IDF]聪明的小羊