`

Digester

    博客分类:
  • XML
阅读更多

Digester框架以模式(Pattern)和规则(Rule)为基础处理输入的XML。模式必须与XML元素匹配,包括其名字和在文档树内的位置。描述匹配模式的语法类似于XPath匹配模式,例如:catalog模式匹配顶层的<catalog>元素,catalog/book模式匹配直接嵌套在<catalog>元素内的<book>元素(但不匹配文档内其他位置的<book>元素)。

所有的模式都必须指定其完整名称——从根元素开始的完整路径。唯一的例外是包含通配符(“*”)的模式,例如*/name模式匹配XML文档内任何位置的<name>元素。但是根元素不必特别指出,因为所有的路径都是从根元素开始的绝对路径。

当Digester发现一个指定的模式,它就执行关联的任务。由此可见,Digester框架显然与SAX解析器有着密切的关系(实际上,Digester类实现了org.xml.sax.ContentHandler,并维护着解析栈)。所有在Digester中使用的规则必须扩展org.apache.commons.digester.Rule,后者本身提供了一些类似于SAX的ContentHandler回调函数的方法。例如,当遇到匹配元素的开始标记和结束标记时,begin()方法和end()方法将分别被调用。

一旦遇到匹配元素的内容,body()方法被调用;最后被调用的方法是finish(),这个方法在匹配元素的结束标记处理完毕之后被调用,用来执行可能需要的事后清理任务。然而,大多数时候我们不必关注这些方法,因为框架提供的标准规则很可能已经提供了所有必需的功能。

要反配制一个文档,首先创建一个org.apache.commons.digester.Digester类的实例,如果必要的话,进行一些配置操作,指定必需的模式和规则,最后向parse()方法传递一个XML文件的引用。下面的DigesterDriver示范了这一处理过程(必须在命令行上指定输入XML文档的名称)。

 

import org.apache.commons.digester.*;
import java.io.*;
import java.util.*;

public class DigesterDriver {
	public static void main(String[] args) {
		try {
			Digester digester = new Digester();
			digester.setValidating(false);
			digester.addObjectCreate("catalog", Catalog.class);
			digester.addObjectCreate("catalog/book", Book.class);
			digester.addBeanPropertySetter("catalog/book/author", "author");
			digester.addBeanPropertySetter("catalog/book/title", "title");
			digester.addSetNext("catalog/book", "addBook");
			digester.addObjectCreate("catalog/magazine", Magazine.class);
			digester.addBeanPropertySetter("catalog/magazine/name", "name");
			digester.addObjectCreate("catalog/magazine/article", Article.class);
			digester.addSetProperties("catalog/magazine/article", "page", "page");
			digester.addBeanPropertySetter("catalog/magazine/article/headline");
			digester.addSetNext("catalog/magazine/article", "addArticle");
			digester.addSetNext("catalog/magazine", "addMagazine");
			File input = new File(args[0]);
			Catalog c = (Catalog) digester.parse(input);
			System.out.println(c.toString());
		} catch (Exception exc) {
			exc.printStackTrace();
		}
	}
}

 

 

在上面的代码中,我们首先创建了Digester类的一个实例digester,然后指定它不要用DTD验证XML文档的合法性——这是因为我们没有为XML文档定义DTD。接下来,我们指定了模式和关联的规则:ObjectCreateRule创建指定类的一个实例,并将它压入解析栈。SetPropertiesRule把Bean属性设置成当前XML元素的属性值——规则的第一个参数是XML属性的名称,第二个参数是Bean属性的名称。

SetPropertiesRule获取的是XML属性的值,而BeanPropertySetterRule获取的是位于当前元素内的原始字符数据值。使用BeanPropertySetterRule时不必指定要设置的Bean属性名字,默认是当前XML元素的名称。在上面的例子中,在匹配catalog/magazine/article/headline模式的规则定义中使用的就是默认值。最后,SetNextRule弹出解析栈顶部的对象,并把该对象传递给它下面对象的指定名称的方法——通常用来把一个配置完毕的Bean插入父对象。

注意,我们可以为同一个模式注册多个规则。如果注册了多个规则,则这些规则按照它们被加入到Digester的次序执行,例如,如果要处理catalog/magazine/article的元素,我们首先创建合适的article Bean,然后设置page属性,最后弹出完成后的article Bean,并把它插入magazine。

 

调用任意方法

我们不仅可以设置Bean的属性,而且还可以调用堆栈内对象的任意方法。这通过CallMethodRule完成,我们只需指定方法名字,如有必要,再说明调用的参数类型和数量。CallParamRule用来定义传递给被调用函数的参数值,参数值可以从当前XML元素的命名的属性获取,也可以从当前元素包含的原始字符数据获取。例如,在前面实现DigesterDriver的例子中,我们可以不用BeanPropertySetterRule,而是通过显式调用属性的set方法达到同样的目的:

 

digester.addCallMethod( "catalog/book/author", "setAuthor", 1 );
digester.addCallParam( "catalog/book/author", 0 );

 

 

上面的第一行代码给出了要调用的方法(即setAuthor()),以及该调用需要的参数数量(即1)。第二行代码的意思是从元素包含的字符数据获取函数参数的值,把它作为参数数组的第一个传入(即索引是0的数组元素)。如果我们指定了XML元素属性的名称(例如digester.addCallParam( "catalog/book/author", 0, "author" );),则参数值将从当前元素的相应属性值获取。

这里必须注意的是,“digester.addCallMethod( "pattern", "methodName", 0 );”这个语句不是指定了一个不带参数的方法调用,而是指定了带有一个参数的方法调用,它的值就是当前XML元素的字符数据!这样,我们又有了另一种替代BeanPropertySetterRule的办法:

 

digester.addCallMethod( "catalog/book/author", "setAuthor", 0 );

  

如果要调用一个确实没有参数的方法,必须采用如下形式:digester.addCallMethod( "pattern", "methodName" );。

 

标准规则概要

下面简要说明所有标准规则。

创建

ObjectCreateRule:利用指定类的默认构造函数,创建该类的一个对象,并把对象压入栈。当元素处理结束时,对象被弹出。被实例化的类可通过class对象或类的全称给出。

FactoryCreateRule:利用指定的工厂类创建一个对象,把对象压入栈。对于没有提供默认构造函数的类,这一规则很有用。用于该规则的工厂类必须实现org.apache.commons.digester.ObjectCreationFactory接口。

设置属性

SetPropertiesRule:利用指定名称的XML元素属性值,设置顶层Bean的一个或者多个指定名称的属性。XML元素的属性名称和Bean的属性名称以String[]数组形式传入该规则(通常用来处理之类的结构)。

BeanPropertySetterRule:把顶层Bean的指定名称的属性设置成当前XML元素包含的字符数据。(通常用来处理<page>10</page>之类的结构)。

SetPropertyRule:设置顶层Bean的一个属性。无论是Bean属性的名称,还是赋予该属性的值,都在当前XML元素中以属性的形式指定,例如:<article key="page" value="10" />。

管理父/子关系

SetNextRule:弹出栈顶的对象,把它传递给紧接其下的另一个对象的指定名称的方法。通常用来把一个已经初始化的Bean插入到父对象。

SetTopRule:把栈里面上数第二的对象传递给顶层的对象。当子对象提供了一个setParenet方法时,这一规则很有用。

SetRootRule:调用栈底对象的一个方法,并把栈顶的对象作为参数传入。

调用任意方法

CallMethodRule:调用顶层Bean的指定名称的方法。被调用的方法可以有任意多个参数,参数的值通过后继的CallParamRule给出。

CallParamRule:表示方法调用的参数。参数的值或者取自指定名称的XML元素的属性,或者是当前元素包含的原始字符数据。这个规则要求用一个整数指定它在参数列表中的位置。

 

通过XML指定规则

在前面的内容中,我们用程序代码的方式指定模式和规则,这些模式和规则都是在编译的时候就已经确定,虽然从概念上来讲比较简单,但却不能说尽善尽美:Digester框架的总体目标是在运行时识别和处理各种数据结构,但如果我们用编程的方法指定模式和规则,则所有行为在编译时已经固定!如果Java源程序中包含了大量固定的字符串,通常意味着程序在执行某些配置操作,这部分操作可以被(或许是应该被)延迟到运行时进行。

org.apache.commons.digester.xmlrules包解决了这个问题。这个包提供了一个DigesterLoader类,它能够从XML文档读取模式/规则对,返回配置好的Digester对象。用来配置Digester对象的XML文档必须遵从digester-rules.dtd,这个DTD是xmlrules包的一部分。

下面就是本文例子的配置文件rules.xml。有几点必须说明。

首先,模式可以用两种方式指定:或者使用<pattern>元素,或者通过代表规则的XML元素的属性。这两种办法可以混合使用,且<pattern>元素是可以嵌套的。其次,<alias>元素和<set-properties-rule>一起使用,用来把XML属性映射到Bean属性。最后,就当前发行的Digester软件包而言,我们不能在配置文件中指定BeanPropertySetterRule,正如前面所介绍的,我们用CallMethodRule来达到同样的目标。

 

<?xml version="1.0"?>
<digester-rules>
	<object-create-rule pattern="catalog" classname="Catalog" />
	<set-properties-rule pattern="catalog">
		<alias attr-name="library" prop-name="library" />
	</set-properties-rule>
	<pattern value="catalog/book">
		<object-create-rule classname="Book" />
		<call-method-rule pattern="author" methodname="setAuthor" paramcount="0" />
		<call-method-rule pattern="title" methodname="setTitle" paramcount="0" />
		<set-next-rule methodname="addBook" />
	</pattern>
	<pattern value="catalog/magazine">
		<object-create-rule classname="Magazine" />
		<call-method-rule pattern="name" methodname="setName" paramcount="0" />
		<pattern value="article">
			<object-create-rule classname="Article" />
			<set-properties-rule>
				<alias attr-name="page" prop-name="page" />
			</set-properties-rule>
			<call-method-rule pattern="headline" methodname="setHeadline" paramcount="0" />
			<set-next-rule methodname="addArticle" />
		</pattern>
		<set-next-rule methodname="addMagazine" />
	</pattern>
</digester-rules>

 

 现在,所有实际的操作都转移到了Digester和DigesterLoader类,XmlRulesDriver类就变得相当简单。运行下面的XmlRulesDriver时,在第一个命令行参数中指定目录文档的名字,在第二个参数中指定rules.xml(注意,DigesterLoader不是从File或者org.xml.sax.InputSource读取rules.xml文件,而是要求指定一个URL,因此,下面代码中File引用被转换成了等价的URL)。

 

import org.apache.commons.digester.*;
import org.apache.commons.digester.xmlrules.*;
import java.io.*;
import java.util.*;

public class XmlRulesDriver {
	public static void main(String[] args) {
		try {
			File input = new File(args[0]);
			File rules = new File(args[1]);
			Digester digester = DigesterLoader.createDigester(rules.toURL());
			Catalog catalog = (Catalog) digester.parse(input);
			System.out.println(catalog.toString());
		} catch (Exception exc) {
			exc.printStackTrace();
		}
	}
}

 

 

结束语:本文对Jakarta Commons Digester的介绍就到这里结束。当然,还有许多内容这里尚未涉及。其中一个在这里忽略的主题是XML名称空间:Digester允许把规则定义成只能对某一个名称空间内定义的元素起作用。

另外,我们简单地提及了通过扩展Rule类开发定制规则的问题。按照习惯,Digester类提供了push()、peek()和pop()方法,使得开发者能够自由地直接操作解析栈

分享到:
评论

相关推荐

    commons-digester3-3.2-API文档-中文版.zip

    赠送jar包:commons-digester3-3.2.jar; 赠送原API文档:commons-digester3-3.2-javadoc.jar; 赠送源代码:commons-digester3-3.2-sources.jar; 赠送Maven依赖信息文件:commons-digester3-3.2.pom; 包含翻译后...

    commons-digester3-3.2-API文档-中英对照版.zip

    赠送jar包:commons-digester3-3.2.jar; 赠送原API文档:commons-digester3-3.2-javadoc.jar; 赠送源代码:commons-digester3-3.2-sources.jar; 赠送Maven依赖信息文件:commons-digester3-3.2.pom; 包含翻译后...

    commons-digester.jar

    `commons-digester.jar`是Apache Commons项目中的一个组件,主要功能是解析XML文档并根据预定义的规则自动创建和填充Java对象。这个组件在Java应用程序中尤其有用,特别是那些需要从XML配置文件中构建复杂对象层次...

    利用commons-digester解析xml

    标题“利用commons-digester解析XML”涉及到的是Java开发中的一种处理XML文档的工具——Apache Commons Digester。这个库提供了一种方便的方式来映射XML文档结构到Java对象,从而简化了XML数据的处理过程。 Apache ...

    commons-digester-2.1.jar

    `commons-digester-2.1.jar` 是Apache Commons项目中的一个组件,主要负责XML文档的解析和对象的创建与绑定。Apache Commons Digester库提供了一种规则驱动的方法来解析XML文档,并根据预定义的规则将XML数据映射到...

    digester用法测试案例

    Digester是Apache软件基金会的Jakarta项目中的一个实用工具库,它主要用来解析XML文档,并根据预定义的规则自动创建和配置Java对象。这个工具在处理XML到Java对象映射时,极大地简化了代码,避免了手动解析XML的繁琐...

    Castor、digester实例

    Castor和Digester是两个在Java开发中用于对象与XML数据之间进行映射的库,它们简化了XML数据的解析和对象的序列化过程。在本文中,我们将深入探讨这两个库,以及如何通过实例来使用它们。 首先,让我们了解Castor。...

    Digester java解析xml

    Java中的Digester库是Apache Commons项目的一部分,它提供了一种方便的方式来解析XML文档,并将解析结果映射到Java对象模型上。这个库特别适合于创建简单的XML到Java对象的映射,而不需要编写大量的手动解析代码。在...

    org.apache.commons.digester解析XML.rar

    Apache Commons Digester是一个Java库,专门用于将XML文档解析成对象结构。这个“org.apache.commons.digester解析XML.rar”压缩包包含了一个测试工程,它演示了如何使用Digester库来解析XML文件并映射到Java对象上...

    Digester读取xml教程.rar

    《使用Digester解析XML的深度指南》 在Java开发中,处理XML文件是常见的任务,而Apache Commons Digester库提供了一种高效且便捷的方式来解析XML并将其映射到Java对象。本教程将深入探讨如何使用Digester来读取XML...

    digester组件简化了xml文件处理操作

    ### Digester组件简化XML文件处理操作 #### 一、引言 随着Web技术的发展,XML作为数据交换格式的重要性日益凸显。然而,对于大型且复杂的XML文档进行解析与处理时,传统的方法如DOM(Document Object Model)和SAX...

    Digester两种解析方式

    在Java开发中,Apache Commons Digester是一个非常有用的库,它允许开发者通过XML配置来实例化、配置和关联Java对象。 Digester提供了两种主要的解析方式,即规则硬编码和独立的规则文件,这两种方法各有其特点和...

    Digester解析XML的小例子(对象嵌套)

    在Java开发中,Struts框架提供了一个强大的工具——Digester,用于解析XML文件并自动创建、配置Java对象。本文将详细介绍如何使用Digester处理具有嵌套结构的XML文档,并通过一个具体的实例——"DigesterXmlTest"来...

    使用Apache_Commons_Digester

    ### 使用Apache Commons Digester开发指南 #### 概述 Apache Commons Digester 是一款基于 Java 的开源库,专门用于简化 XML 文件解析的过程。它利用 SAX(Simple API for XML)解析器来解析 XML 数据,并通过一...

    Jakarta-Common-Digester使用笔记

    Digester不是一个XML Parser,它只是对SAX更高层次上的一个封装使用Digester,将XML映射成javaBean. 我们无须了解SAX和DOM的解析过程,只要给Digester添加一些解析规则,就能对一个xml文件进行解析。Digester使用...

    commons-digester-1.8.1-API文档-中英对照版.zip

    赠送jar包:commons-digester-1.8.1.jar; 赠送原API文档:commons-digester-1.8.1-javadoc.jar; 赠送源代码:commons-digester-1.8.1-sources.jar; 赠送Maven依赖信息文件:commons-digester-1.8.1.pom; 包含...

    xml解析commons-digester的demo

    Apache Commons Digester是Java中一个强大的工具,它提供了方便的方式来解析XML文档,并将解析出的数据绑定到Java对象上,实现对象的自动创建和初始化。本示例将详细介绍如何使用Apache Commons Digester进行XML解析...

    digester解析xml必备包.rar

    这个“digester解析xml必备包.rar”包含了三个关键的jar包,它们是实现Digester功能所必需的。 1. **commons-logging-1.2.jar**:这是Apache Commons Logging库的版本1.2。它提供了一个抽象层,允许开发者使用多种...

    commons-digester-1.7.zip

    Commons Digester是一个强大的Java库,它允许开发人员根据XML文档中的模式规则来创建和操作对象。这个"commons-digester-1.7.zip"文件包含了Apache Commons Digester库的1.7版本,这是一个广泛用于处理XML到Java对象...

Global site tag (gtag.js) - Google Analytics