使用Digester
基本概念
1. 在Digester的内部采用SAX来解析XML文件。为了能够正确的使用它,必须在解析之前进行相应的设置。同时,在解析xml文件的过程中,它使用Stack来保存和检索这个期间产生的对象。
2. 为了简化使用,它通过匹配模式来定位要解析的xml标签。匹配模式的例子如下:
xml文件:
<?xml version="1.0"?>
<students>
<student>
<name>Java Boy</name>
<course>JSP</course>
</student>
<student>
<name>Java Girl</name>
<course>EJB</course>
</student>
</students>
每个标签与相应的匹配模式对应如下表:
标签
匹配模式
<students>
students
<student>
students/student
<name>
students/student/name
<course>
students/student/course
如果将xml文件结构视为一颗树的话,那么每个标签的匹配模式就是从根元素到这个元素的路径。除了使用具体的标签,还可以使用通配符。
3. 使用匹配模式可以很方便的定位需要处理的元素,为了处理这些元素,需要定义处理规则。规则在匹配模式被找到时起作用。所有的规则都是从org.apache.commons.digester.Rule派生的。所有已定义的Rule对象,可以在org.apache.commons.digester中找到。常用的规则:
- ObjectCreate,创建对象实例。
- SetProperties,将标签属性(Attribute)与要创建的对象的属性相关联。
- BeanPropertySetter,将标签所包含标签与要创建的对象的属性相关联。
- SetNext,设置遇到下一个标签时的动作。
- CallMethod,设置当匹配模式被找到时要调用的方法。
- CallParam,设置对应的callMethod中指定方法所需要的参数值。
基本使用
以正确的顺序调用Digester方法是成功使用Digester处理XML文件的关键。使用步骤如下:
1. 创建org.apache.commons.digester.Digester实例并配置,包括设置实现Digester Rule的对象。
2. 使用Digester的push方法在Digester使用的stack中放置一个初始对象。在解析xml文件的过程中,Digester使用stack来保存它所找到的对象。第一个对象在遇到第一个标签时被放置到stack中,当最后一个标签处理完毕时被弹出。为了最后能检索到这个对象,因此需要一个初始对象来保留一个指向它的引用。
3. 注册匹配模式和rule。
4. 调用parse来解析xml文件。
使用举例
1. 简单例子,从一个xml文件中创建对象。
XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<name>Java Boy</name>
<course>JSP</course>
</student>
<student>
<name>Java Girl</name>
<course>EJB</course>
</student>
</students>
要创建的对象:
public class Student {
private String name;
private String course;
……
}
解析:
public class DigesterStudy {
private Vector students;
public DigesterStudy(){
students= new Vector( 5);
}
public static void main(String[] args) {
DigesterStudy ds= new DigesterStudy();
ds.digest();
}
public void digest(){
//创建实例
Digester digester= new Digester();
//将初始对象压入digester的stack
digester.push( this);
//指明匹配模式和要创建的类
digester.addObjectCreate( "students/student", Student.class);
//设置对象属性
digester.addBeanPropertySetter( "students/student/name");
digester.addBeanPropertySetter( "students/student/course");
//当移动到下一个标签中时的动作
digester.addSetNext( "students/student", "addStudent");
try {
//解析
DigesterStudy ds= (DigesterStudy)digester.parse( getClass()
.getClassLoader()
.getResourceAsStream( "students.xml"));
System.out.print( ds);
} catch (Exception e) {
e.printStackTrace();
}
}
public void addStudent( Student student){
students.add( student);
}
public String toString(){
return students.toString();
}
}
2. 复杂例子,从xml文件中创建相互之间有关系的对象。
XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<academy name="JAcademy" >
<student name="JavaBoy" division="A">
<course>
<id>C1</id>
<name>JSP</name>
</course>
<course>
<id>C2</id>
<name>Servlets</name>
</course>
</student>
<student name="JavaGirl" division="B">
<course>
<id>C3</id>
<name>EJB</name>
</course>
</student>
<teacher name="JavaGuru">
<certification>SCJP</certification>
<certification>SCWCD</certification>
</teacher>
<teacher name="JavaMaster">
<certification>OCP</certification>
<certification>SCJP</certification>
<certification>SCEA</certification>
</teacher>
</academy>
要创建的对象:
public class Academy {
private String name;
private Vector students;
private Vector teachers;
……
}
public class Student {
private String name;
private String division;
private Vector courses;
……
}
public class Course {
private String id;
private String name;
……
}
public class Teacher {
private String name;
private Vector certifications;
……
}
其中的<certification>在程序中对应一个字符串,故而没有列出。
解析:
public void digest(){
Digester digester= new Digester();
//注意,此处并没有象上例一样使用push,是因为此处从根元素创建了一个对//象实例
digester.addObjectCreate( "academy", Academy.class);
//将< academy >的属性与对象的属性关联
digester.addSetProperties( "academy");
digester.addObjectCreate( "academy/student", Student.class);
digester.addSetProperties( "academy/student");
digester.addObjectCreate( "academy/student/course", Course.class);
digester.addBeanPropertySetter( "academy/student/course/id");
digester.addBeanPropertySetter( "academy/student/course/name");
digester.addSetNext( "academy/student/course", "addCourse");
digester.addSetNext( "academy/student", "addStudent");
digester.addObjectCreate( "academy/teacher", Teacher.class);
digester.addSetProperties( "academy/teacher");
//当遇到academy/teacher/certification时,调用addCertification
digester.addCallMethod( "academy/teacher/certification",
"addCertification", 1);
//设置addCertification的参数值,此处的0表示这个元素体的第一个值
//为参数值传入addCertification。在此处,即为<certification>的值。
//(因为就只有一个)
digester.addCallParam( "academy/teacher/certification", 0);
digester.addSetNext( "academy/teacher", "addTeacher");
try {
Academy a= (Academy)digester.parse( getClass()
.getClassLoader()
.getResourceAsStream( "students.xml"));
System.out.print( a);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
3. 从配置文件中创建Digester,通过DigesterLoader可以从配置文件中创建Digester实例,从而省去类似于上例手工配置Digester的代码。
Digester的配置文件,对应上例的配置文件如下:
<?xml version="1.0"?>
<digester-rules>
<pattern value="academy">
<object-create-rule classname="Academy" />
<set-properties-rule />
<pattern value="student">
<object-create-rule classname="Student" />
<set-properties-rule />
<pattern value="course">
<object-create-rule classname="Course" />
<bean-property-setter-rule pattern="id"/>
<bean-property-setter-rule pattern="name"/>
<set-next-rule methodname="addCourse" />
</pattern>
<set-next-rule methodname="addStudent" />
</pattern>
<pattern value="teacher">
<object-create-rule classname="Teacher" />
<set-properties-rule />
<call-method-rule pattern="certification" methodname="addCertification"
paramcount="1" />
<call-param-rule pattern="certification" paramnumber="0"/>
<set-next-rule methodname="addTeacher" />
</pattern>
</pattern>
</digester-rules>
使用配置文件之后,上例的代码变为:
Digester digester = DigesterLoader.createDigester(
this.getClass().getClassLoader().getResource("academyRules.xml"));
Academy a= (Academy)digester.parse( getClass()
.getClassLoader().getResourceAsStream( "students.xml"));
注意
在使用Digester需要注意的地方:
- 调用顺序,正确的调用顺序才能得出正确的结果。方法调用顺序基本和标签在xml文件中的层次关系相对应。基本的顺序是:先创建对象;然后设置属性;随后处理子元素;最后设置遇到下一个元素所对应的动作。对于子元素的处理,是同样的过程。
- 正确的使用初始对象。对比上面2个例子,之所以在第一个例子中显示的调用了digester的push方法,其原因就在于我们并没有如第二个例子一样用xml的root元素创建一个实例。如果不显式的调用,我们将会丢失这个元素的引用,那么也就无法得到后续的对象。
- digester的addSetNex方法中所指定的方法实际上是包含匹配模式对应标签的父标签对应对象的方法。在上两个例子中addStudent,都是包含Student对象的那个对象的方法。对于第一个例子,是DigesterStudy;对于第二个例子,是Academy。而且它的位置通常是在创建对象语句组的最后,与addObjectCreate相对应。在这2个语句之间的代码中所指定的方法都是所创建对象的方法。而且它们的顺序与匹配模式所对应的标签的顺序必须是一致的。
- 使用配置文件来创建digester,这样会带来很大的灵活性。
分享到:
相关推荐
本文将深入探讨如何使用Apache的 Digester 库来解析XML文档,这是一款强大的工具,能够将XML数据映射到Java对象,简化了处理XML的过程。 Digester 是Apache Commons项目的一部分,它提供了一种规则驱动的方法来处理...
### 使用Digester解析XML文档示例 #### 一、Digester简介与应用场景 Digester是Apache Jakarta项目下的一个工具类库,它简化了基于SAX(Simple API for XML)的XML解析过程。Digester能够根据定义好的规则自动将...
本篇文章将深入探讨如何使用Digester和`rule.xml`配置文件来解析自定义的XML文件。 首先,让我们了解什么是Apache Digester。Digester是一个开源库,它提供了从XML到Java对象的映射功能。通过定义一系列的“消化...
使用Digester的基本步骤如下: 1. 创建一个`Digester`实例。实例化后,它可以安全地重复使用,但需要注意的是,它是非线程安全的。 2. 配置`Digester`属性,例如设置是否验证XML文档。 3. 添加处理规则,这些规则...
不错的解析XML的类,主要利用org.apache.commons.digester.Digester;
Digester使用堆栈来保存xml节点(stack.push()方法),当该xml节点中嵌套的所有子节点解析完毕,该节点将被弹出(stack.pup()方法)。Digester最大的优点就是使用模式匹配来表示xml文件中节点之间的父子关系 。
- **配置文件解析**:在很多框架中,如Spring,都使用类似Digester的方式解析XML配置文件,创建和配置对象。 - **对象的自动构建**:通过XML描述, Digester可以自动生成对象树,并按照XML结构设置对象属性,极大地...
### 使用Apache Commons Digester开发指南 #### 概述 Apache Commons Digester 是一款基于 Java 的开源库,专门用于简化 XML 文件解析的过程。它利用 SAX(Simple API for XML)解析器来解析 XML 数据,并通过一...
《使用Digester解析XML的深度指南》 在Java开发中,处理XML文件是常见的任务,而Apache Commons Digester库提供了一种高效且便捷的方式来解析XML并将其映射到Java对象。本教程将深入探讨如何使用Digester来读取XML...
1. **初始化 Digester**: 在使用 Digester 之前,我们需要创建一个 Digester 实例,并设置一些基本配置,例如XML解析器的命名空间处理等。然后可以通过 `addRuleSet` 方法添加预定义的规则集,或者通过 `addRule` ...
Castor和Digester是两个在Java开发中用于对象与XML数据之间进行映射的库,它们简化了XML数据的解析和...通过上述实例,你应该对如何使用Castor和Digester有了基本的理解,但要完全掌握它们,还需要进一步的实践和学习。
1. **XML解析**:Digester使用SAX解析器处理XML文档,而不是DOM解析器,这意味着它在处理大型XML文件时内存效率更高。SAX解析器逐行读取XML,当遇到特定的元素时触发回调方法。 2. **规则匹配**:通过`addRule()`...
在提供的案例中,`digester`文件很可能包含了一个使用Digester解析XML的示例程序,可能包括了规则的定义、XML文档的结构以及解析后的结果展示。通过分析这个案例,你可以更好地理解如何在实际项目中运用Digester来...
在提供的文件列表中,有一个名为“Privilege”的文件,这可能是示例中的一个权限或者角色相关的类,或者是一个XML配置文件,用于演示如何使用Digester解析与权限或角色相关的XML数据。具体用途可能需要参考实际的...
在本文中,我们将深入探讨Java解析XML文件,特别是使用Digester库的过程。 1. **Java解析XML的基本概念** 在Java中,解析XML文件通常有两种主要方法:DOM(Document Object Model)和SAX(Simple API for XML)。...
- **栈数据结构**: 在解析过程中,Digester使用栈来保存和检索生成的Java对象。这种方式有利于处理嵌套层次较深的XML元素。 ##### 2. 模式匹配 - Digester通过匹配模式来定位XML文件中的元素。模式匹配是一种灵活的...
本文将深入探讨digester包的原理、使用方法以及在实际项目中的应用。 首先,让我们了解什么是Apache Commons Digester。digester是一个开源Java库,它通过定义规则来解析XML文档,这些规则决定了当XML文档中的特定...
在使用Digester时,Logging库可以帮助记录解析过程中的信息,便于调试和问题定位。 2. **commons-digester-2.1.jar**:这是Apache Commons Digester的核心库,版本2.1。Digester通过匹配XML文档中的模式(如元素名...
在与digester结合使用时,它能帮助找到XML配置文件中引用的服务或者类,使得动态加载和配置成为可能。例如,当XML配置文件中包含类名但未提供完全限定路径时,commons-discovery可以自动查找并加载相应的类。 在...