首先要搞清楚,digester是按栈(先进后出)的方式去解析rule的,即【先执行的代码后生效】
废话不多说,看实例的结构:
解析rule需要将xml文件和java对象关联起来,所有先创建两个java对象:
//学校
public class School {
String name;
String address;
//一座学校包含多个老师
List<Teacher> teachers = new ArrayList<Teacher>();
//添加老师
public void addTeacher(Teacher teacher){
teachers.add(teacher);
}
//打印
public String toString(){
System.out.print("School:["+"name="+this.name+",naddress="+this.address);
for(int i=0;i<this.teachers.size();i++){
System.out.print(",teacher"+i+"="+this.teachers.get(i).getName());
}
System.out.println("]");
return null;
}
//自行添加属性对应的get和set方法
}
//老师
public class Teacher {
long code;
String name;
int age;
String sex;
//打印
public String toString() {
System.out.println("Teacher [code=" + this.getCode() + ", name=" + this.getName() + ", age=" + this.getAge()
+ ", sex=" + this.getSex() + "]");
return null;
}
//自行添加属性对应的get和set方法
}
接下来创建一个带有数据的xml文件,它就是我们要解析的文件:
<?xml version="1.0"?>
<school>
<name>华南理工大学广州学院</name>
<address>花都区</address>
<teacher name="李老师" age='22'>
<name>洋平化</name>
<code>1001001</code>
<sex>男</sex>
<age>50</age>
</teacher>
<teacher name="Liu老师" age="32">
<name>洋平化</name>
<code>1001001</code>
<sex>男</sex>
<age>50</age>
</teacher>
</school>
最后,创建解析xml的rule文件,其实看英文标签都能理解其意思了,注意设置对象的属性有两种方法,第一种是通过<bean-property-setter-rule>读取<school>标签下的【子标签】,另一种是通过调用setXXX的方法读取<school>标签中的【属性】
<?xml version="1.0"?>
<!DOCTYPE digester-rules
PUBLIC "-//Jakarta Apache //DTD digester-rules XML V1.0//EN"
"http://jakarta.apache.org/commons/digester/dtds/digester-rules.dtd">
<digester-rules>
<!-- value是匹配的节点的名字 -->
<pattern value="school">
<!-- 当匹配到school标签时,就创建一个digester.School对象 -->
<object-create-rule classname="digester.School" />
<!-- 将<school>标签下的内容设置到digester.School对应的属性中 -->
<bean-property-setter-rule pattern="name"/>
<bean-property-setter-rule pattern="address"/>
<!-- 调用digester.School对象中的toString()方法 -->
<call-method-rule methodname="toString"/>
<!-- 匹配<teacher>标签 -->
<pattern value="teacher">
<!-- 创建teacher对象 -->
<object-create-rule classname="digester.Teacher" />
<!-- 回调digester.School对象中的addTeacher方法 -->
<set-next-rule methodname="addTeacher"/>
<!-- 调用digester.Teacher对象中的toString()方法 -->
<call-method-rule methodname="toString"/>
<!-- 调用方法并设置属性 -->
<call-method-rule methodname="setName" paramcount="1"/>
<call-param-rule paramnumber="0" attrname="name"/>
</pattern>
</pattern>
</digester-rules>
最后创建解析工具类,这里要先加入jar包(包括commons-logging-1.2.jar、commons-digester-2.1.jar、commons-beanutils-1.9.3.jar)
下载地址:https://download.csdn.net/download/kshon/11592478
public class DigesterTest {
public void parse(){
Digester dig = DigesterLoader.createDigester(this.getClass().getClassLoader().getResource("digester/school-rule.xml"));
try {
School s = (School) dig.parse(this.getClass().getClassLoader().getResourceAsStream("digester/school.xml"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new DigesterTest().parse();
}
}
输出结果为:
1、在这里有一个坑,那就是前面说的先进后出,例如你在rule.xml文件中把设置属性的方法移到前面,那么它就会最后执行,这样就导致调用其它方法的时候读不出属性值,但是【回调方法】不管放在哪个位置都是最后执行
结果为: