转自:
下文笔者讲述Apache commons digester组件的简介说明,如下所示
Apache commons digester组件简介说明
digester组件简化xml文件处理操作 能将xml文件预先定义的规则(采用编码形式或xml配置文件形式) 映射成java对象 digester组件现在最新版本是2.0 它所依赖的组件是:commons-logging(推荐1.1版本),BeanUtils(推荐1.8版本) 还有需要jdk1.5
Apache commons digester组件解析原理
在Digester中采用SAX来解析XML文件 解析xml文件时, 它使用Stack来保存和检索这个期间产生的对象
例:
<?xml version="1.0"?> <students> <student> <name>maomao</name> <course>java</course> </student> <student> <name>chengcheng</name> <course>python</course> </student> </students> 每个标签与相应的匹配模式对应如下表: 标签 匹配模式 <students> students <student> students/student <name> students/student/name <course> students/student/course
使用匹配模式可以很方便的定位需要处理的元素
为了处理这些元素,需要定义处理规则
规则在匹配模式被找到时起作用
所有的规则都是从org.apache.commons.digester.Rule派生的
所有已定义的Rule对,都在org.apache.commons.digester中
常用的规则: - ObjectCreate,创建对象实例。 - SetProperties,将标签属性(Attribute)与要创建的对象的属性相关联。 - BeanPropertySetter,将标签所包含标签与要创建的对象的属性相关联。 - SetNext,设置遇到下一个标签时的动作。 - CallMethod,设置当匹配模式被找到时要调用的方法。 - CallParam,设置对应的callMethod中指定方法所需要的参数值。
例
1.xml文件: <?xml version="1.0" encoding="UTF-8"?> <students> <student> <name>maomao</name> <course>Java</course> </student> <student> <name>chengcheng</name> <course>python</course> </student> </students> 2.硬编码形式实现 Student类 package com.java265; public class Student { private String name; private String course; public void setName(String name){ this.name=name; } public void setCourse(String course){ this.course=course; } public String getName(){ return this.name; } public String getCourse(){ return this.course; } } 处理类 package com.java265; import org.apache.commons.digester.*; import org.apache.commons.logging.*; import java.io.IOException; import java.util.Vector; import org.apache.commons.digester.xmlrules.*; import org.xml.sax.SAXException; public class DigestTest { private Log log=LogFactory.getLog(this.getClass()); private Vector students; public DigestTest(){ students= new Vector(5); } public void addStudent( Student student){ students.add( student); } public String toString(){ return ((Student)students.get(0)).getName(); } public void digest(){ //digest2.0支持jdk1.5,并且依赖 logging 1.1.1 和 beanutils 1.8.0 //创建实例 Digester digester= new Digester(); //将初始对象压入digester的stack digester.push( this); //指明匹配模式和要创建的类 digester.addObjectCreate( "students/student", Student.class); //设置对象属性 // digester digester.addBeanPropertySetter( "students/student/name"); digester.addBeanPropertySetter( "students/student/course"); //当移动到下一个标签中时的动作 digester.addSetNext( "students/student", "addStudent"); try { //解析,xml文件放在classpath下 DigestTest ds= (DigestTest)digester.parse( getClass().getClassLoader().getResourceAsStream( "students.xml")); log.info(ds); } catch (Exception e) { e.printStackTrace(); } } public static void main(String args[]){ DigestTest test=new DigestTest(); test.digest(); } }
配置文件方式实现
配置文件
studentsRule.xml
<?xml version="1.0"?> <digester-rules> <pattern value="students"> <object-create-rule classname="com.java265.Students" /> <set-properties-rule /> <pattern value="student"> <object-create-rule classname="com.java265.Student" /> <bean-property-setter-rule pattern="name"/> <bean-property-setter-rule pattern="course"/> <set-next-rule methodname="addStudent" /> </pattern> </pattern> </digester-rules> Student类 package com.java265; public class Student { private String name; private String course; public void setName(String name){ this.name=name; } public void setCourse(String course){ this.course=course; } public String getName(){ return this.name; } public String getCourse(){ return this.course; } } Students类 package com.java265; import java.util.Vector; public class Students { private Vector students; public Students(){ students= new Vector(5); } public void addStudent( Student student){ students.add( student); } public String toString(){ return ((Student)students.get(0)).getName(); } } 处理类 package com.java265; import org.apache.commons.digester.*; import org.apache.commons.logging.*; import java.io.IOException; import java.util.Vector; import org.apache.commons.digester.xmlrules.*; import org.xml.sax.SAXException; public class DigestTest { private Log log=LogFactory.getLog(this.getClass()); public void digestByConfig(){ Digester digester = DigesterLoader.createDigester(this.getClass().getClassLoader().getResource("studentsRule.xml")); try { Students a= (Students)digester.parse( this.getClass().getClassLoader().getResourceAsStream("students.xml")); System.out.println(a); log.info(a); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } public static void main(String args[]){ DigestTest test=new DigestTest(); test.digestByConfig(); } }
使用Digester需要注意的地方
1:调用顺序,正确的调用顺序才能得出正确的结果 方法调用顺序基本和标签在xml文件中的层次关系相对应 基本的顺序是:先创建对象;然后设置属性;随后处理子元素;最后设置遇到下一个元素所对应的动作 对于子元素的处理,是同样的过程。 2:正确的使用初始对象 3:digester的addSetNex方法中所指定的方法 实际上是包含匹配模式对应标签的父标签对应对象的方法 在上两个例子中addStudent,都是包含Student对象的那个对象的方法 对于第一个例子,是DigesterTest;对于第二个例子,是Students。 而且它的位置通常是在创建对象语句组的最后,与addObjectCreate相对应。 在这2个语句之间的代码中所指定的方法都是所创建对象的方法。而且它们的顺序与匹配模式所对应的标签的顺序必须是一致的。 4:使用配置文件来创建digester,这样会带来很大的灵活性