登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

经验沉淀 知识结晶

技术因为专注才彻底。

 
 
 

日志

 
 

使用Apache Commons Digester (转)  

2011-06-23 17:24:29|  分类: java |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
本文主要参考了The serverside上的一篇文章。描述了2种典型的使用digester的方法,以及所需要注意的地方。详细内容请参见正文。 

Apache Commons Digester

 简化xml文件处理,它依赖的组件:BeanUtilsLoggingCollections

基本概念

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. 使用Digesterpush方法在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();

 //将初始对象压入digesterstack

 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"));

  评论这张
 
阅读(2419)| 评论(1)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018