在我们的项目中或多或少会采用xml来做配置文件,你可以采用Java原生支持的sax、DOM或者第三方的dom4j等。虽然提供了各式各样的解析方式,但是解析一个复杂的xml所编写的Java代码是非常麻烦的,尤其是当xml做了修改,你会发现你又要修改Java代码。

Apache的commons项目中Digester项目解决了这个问题,它可以很轻易地将xml文件解析成Java对象,让你直接去使用,而你仅仅需要去预定义一份解析规则。

而对于解析规则,你可以采用Java的方式定义、xml的方式定义亦或者annotation的方式定义。

要使用digester需要引入依赖:

<!--apache commons digester-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-digester3</artifactId>
<version>3.2</version>
</dependency>

假设我们要解析如下school.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<school>
<classes>
<class className="classOne">
<student>
<no>1</no>
<name>小张</name>
<age>24</age>
</student>
<student>
<no>2</no>
<name>小李</name>
<age>24</age>
</student>
<student>
<no>1</no>
<name>小王</name>
<age>24</age>
</student>
</class>
</classes>
</school>

我们需要预定义Student、Class、School节点的Java类与之对应

package cn.lay.demo.digester.definition;

/**
* 学生节点
* @author lay
* @date 2018/10/16 23:35
*/
public class StudentDefinition { private Integer no; private String name; private Integer age; public Integer getNo() {
return no;
} public void setNo(Integer no) {
this.no = no;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} @Override
public String toString() {
return "StudentDefinition{" +
"no=" + no +
", name='" + name + '\'' +
", age=" + age +
'}';
}
} package cn.lay.demo.digester.definition; import java.util.ArrayList;
import java.util.List; /**
* 班级节点
* @author lay
* @date 2018/10/16 23:36
*/
public class ClassDefinition { private String className; private List<StudentDefinition> studentDefinitionList = new ArrayList<>(); public String getClassName() {
return className;
} public void setClassName(String className) {
this.className = className;
} public List<StudentDefinition> getStudentDefinitionList() {
return studentDefinitionList;
} public void setStudentDefinitionList(List<StudentDefinition> studentDefinitionList) {
this.studentDefinitionList = studentDefinitionList;
} public void addStudent(StudentDefinition studentDefinition) {
studentDefinitionList.add(studentDefinition);
} @Override
public String toString() {
return "ClassDefinition{" +
"className='" + className + '\'' +
", studentDefinitionList=" + studentDefinitionList +
'}';
}
} package cn.lay.demo.digester.definition; import java.util.ArrayList;
import java.util.List; /**
* 学校节点
* @author lay
* @date 2018/10/16 23:37
*/
public class SchoolDefinition { private List<ClassDefinition> classDefinitions = new ArrayList<>(); public List<ClassDefinition> getClassDefinitions() {
return classDefinitions;
} public void setClassDefinitions(List<ClassDefinition> classDefinitions) {
this.classDefinitions = classDefinitions;
} public void addClass(ClassDefinition classDefinition) {
classDefinitions.add(classDefinition);
} @Override
public String toString() {
return "SchoolDefinition{" +
"classDefinitions=" + classDefinitions +
'}';
}
}

1、Java方式配置解析规则

rule

package cn.lay.demo.digester.rule;

import cn.lay.demo.digester.definition.ClassDefinition;
import cn.lay.demo.digester.definition.SchoolDefinition;
import cn.lay.demo.digester.definition.StudentDefinition;
import org.apache.commons.digester3.Digester; import java.net.URL; /**
* java方式定义解析规则
* @author lay
* @date 2018/10/16 23:38
*/
public class DigesterRule { /**
* 解析
* @param filePath
* @return
*/
public SchoolDefinition execute(String filePath) throws Exception{
Digester digester = new Digester();
digester.setValidating(false);
// classes node
digester.addObjectCreate("school/classes", SchoolDefinition.class);
// class node
digester.addObjectCreate("school/classes/class", ClassDefinition.class);
// set properties
digester.addSetProperties("school/classes/class");
// student node
digester.addObjectCreate("school/classes/class/student", StudentDefinition.class);
// set properties
digester.addBeanPropertySetter("school/classes/class/student/no");
digester.addBeanPropertySetter("school/classes/class/student/name");
digester.addBeanPropertySetter("school/classes/class/student/age");
// add student
digester.addSetNext("school/classes/class/student", "addStudent");
// add class
digester.addSetNext("school/classes/class", "addClass");
// parse
URL url = this.getClass().getClassLoader().getResource(filePath);
System.out.println("url=" + url.toString());
return digester.parse(url);
}
}

测试

@Test
public void testJavaRule() throws Exception {
SchoolDefinition schoolDefinition = new DigesterRule().execute("school.xml");
System.out.println(schoolDefinition);
}

2、xml方式配置解析规则

rule

<!DOCTYPE digester-rules PUBLIC
"-//Apache Commons //DTD digester-rules XML V1.0//EN"
"http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd">
<digester-rules>
<!--school node-->
<pattern value="school/classes">
<object-create-rule classname="cn.lay.demo.digester.definition.SchoolDefinition"/>
<!--class node-->
<pattern value="class">
<object-create-rule classname="cn.lay.demo.digester.definition.ClassDefinition"/>
<set-properties-rule/>
<!--student node-->
<pattern value="student">
<object-create-rule classname="cn.lay.demo.digester.definition.StudentDefinition"/>
<bean-property-setter-rule pattern="no"/>
<bean-property-setter-rule pattern="name"/>
<bean-property-setter-rule pattern="age"/>
<set-next-rule methodname="addStudent"/>
</pattern>
<set-next-rule methodname="addClass"/>
</pattern>
</pattern> </digester-rules>

测试

@Test
public void testXmlRule() throws Exception {
Digester digester = DigesterLoader.newLoader(new XmlRulesModule()).newDigester();
URL url = this.getClass().getClassLoader().getResource("school.xml");
System.out.println("url=" + url);
SchoolDefinition schoolDefinition = digester.parse(url);
System.out.println(schoolDefinition);
} class XmlRulesModule extends FromXmlRulesModule { @Override
protected void loadRules() {
loadXMLRules(this.getClass().getClassLoader().getResourceAsStream("rule/schoolRule.xml"));
}
}

3、注解方式配置解析规则

基于零配置思想,digester支持采用annotation来注解相应的解析规则。

rule

package cn.lay.demo.digester.definition;

import org.apache.commons.digester3.annotations.rules.ObjectCreate;
import org.apache.commons.digester3.annotations.rules.SetNext;
import org.apache.commons.digester3.annotations.rules.SetRoot; import java.util.ArrayList;
import java.util.List; /**
* 学校节点
* @author lay
* @date 2018/10/16 23:37
*/
@ObjectCreate(pattern = "school/classes")
public class SchoolDefinition { private List<ClassDefinition> classDefinitions = new ArrayList<>(); public List<ClassDefinition> getClassDefinitions() {
return classDefinitions;
} public void setClassDefinitions(List<ClassDefinition> classDefinitions) {
this.classDefinitions = classDefinitions;
} @SetNext
public void addClass(ClassDefinition classDefinition) {
System.out.println("执行了addClass");
classDefinitions.add(classDefinition);
} @Override
public String toString() {
return "SchoolDefinition{" +
"classDefinitions=" + classDefinitions +
'}';
}
} package cn.lay.demo.digester.definition; import org.apache.commons.digester3.annotations.rules.*; import java.util.ArrayList;
import java.util.List; /**
* 班级节点
* @author lay
* @date 2018/10/16 23:36
*/
@ObjectCreate(pattern = "school/classes/class")
public class ClassDefinition { @SetProperty(pattern = "school/classes/class")
private String className; private List<StudentDefinition> studentDefinitionList = new ArrayList<>(); public String getClassName() {
return className;
} public void setClassName(String className) {
this.className = className;
} public List<StudentDefinition> getStudentDefinitionList() {
return studentDefinitionList;
} public void setStudentDefinitionList(List<StudentDefinition> studentDefinitionList) {
this.studentDefinitionList = studentDefinitionList;
} @SetNext
public void addStudent(StudentDefinition studentDefinition) {
System.out.println("执行了addStudent");
studentDefinitionList.add(studentDefinition);
} @Override
public String toString() {
return "ClassDefinition{" +
"className='" + className + '\'' +
", studentDefinitionList=" + studentDefinitionList +
'}';
}
} package cn.lay.demo.digester.definition; import org.apache.commons.digester3.annotations.rules.BeanPropertySetter;
import org.apache.commons.digester3.annotations.rules.ObjectCreate; /**
* 学生节点
* @author lay
* @date 2018/10/16 23:35
*/
@ObjectCreate(pattern = "school/classes/class/student")
public class StudentDefinition { @BeanPropertySetter(pattern = "school/classes/class/student/no")
private Integer no; @BeanPropertySetter(pattern = "school/classes/class/student/name")
private String name; @BeanPropertySetter(pattern = "school/classes/class/student/age")
private Integer age; public Integer getNo() {
return no;
} public void setNo(Integer no) {
this.no = no;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} @Override
public String toString() {
return "StudentDefinition{" +
"no=" + no +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}

测试

@Test
public void testAnnotationRule() throws Exception {
Digester digester = DigesterLoader.newLoader(new FromAnnotationsRuleModule() {
@Override
protected void configureRules() {
// 这里只添加SchoolDefinition即可
bindRulesFrom(SchoolDefinition.class);
}
}).newDigester();
URL url = this.getClass().getClassLoader().getResource("school.xml");
System.out.println("url=" + url);
SchoolDefinition schoolDefinition = digester.parse(url);
System.out.println(schoolDefinition);
}

digester解析xml文件的更多相关文章

  1. 解析XML文件示例

    项目中要解析Xml文件,于是在工程里找了下前人写例子. 1,SAX(基于事件,效率高,使用声明加载什么). public class MVCConfig { private static MVCCon ...

  2. apache.commoms.digester3 解析xml文件

    Technorati 标签: java,xml,digester,xmlrule,FromXmlRulesModule 1 简介 java解析xml,就个人所知有3种方法DOM.SAX和Digeste ...

  3. Digester解析xml原理

    Tomcat内部是使用Digester来解析xml文件的,将xml转化为java对象. digester底层是基于SAX+事件驱动+栈的方式来搭建实现的,SAX主要用来解析xml,事件驱动主要是在解析 ...

  4. Android 解析XML文件和生成XML文件

    解析XML文件 public static void initXML(Context context) { //can't create in /data/media/0 because permis ...

  5. JAVA使用SAX解析XML文件

    在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...

  6. JAVA中使用DOM解析XML文件

    XML是一种方便快捷高效的数据保存传输的格式,在JSON广泛使用之前,XML是服务器和客户端之间数据传输的主要方式.因此,需要使用各种方式,解析服务器传送过来的信息,以供使用者查看. JAVA作为一种 ...

  7. java中采用dom4j解析xml文件

    一.前言 在最近的开发中用到了dom4j来解析xml文件,以前听说过来解析xml文件的几种标准方式:但是从来的没有应用过来,所以可以在google中搜索dmo4j解析xml文件的方式,学习一下dom4 ...

  8. XML:使用DOM技术解析xML文件中的城市,实现select级联选择

    中国的城市xml格式:cities.xml <?xml version="1.0" encoding="utf-8"?> <china> ...

  9. dom4j如何解析XML文件

    最近在 一些对xml文件的操作,下面简单写一个dom4j解析xml文件并将其封装到一个javabean中的例子,只是具有针对性的,不是通用的,仅供参考哦~~ 首先说:dom4j是一个java的XML ...

随机推荐

  1. 前端切图要选择png和jpg呢?

    今天特意验证了一下: 切完图分别保存png24.png8和jpg60.jpg80(60和80表示保存图片时品质选择)后, 然后再压缩图片,压缩图片地址:https://tinypng.com/ 图片直 ...

  2. kali linux之steghide

    Steghide  Linux 命令行隐写工具 Steghide是一款开源的隐写术软件,它可以让你在一张图片或者音频文件中隐藏你的秘密信息,而且你不会注意到图片或音频文件发生了任何的改变.而且,你的秘 ...

  3. windows文件名太长无法删除的解决办法

    安装nodejs 的模块hexo后,由于香重新安装,在删除的时候却提示文件名太长无法删除,dos命令.回收站各种都无法搞定,后来找到解决办法: 1.进入这些文件的所在目录的上层目录,右键这些文件的所在 ...

  4. nginx配置文件中,location字段里面的root字段和别名alias

    1. location里面的root例子 server{ listen ; server_name www.wzw.com; location /www { root /data/; //设置虚拟主机 ...

  5. Flutter 1.0 正式版: Google 的便携 UI 工具包

    简评:所以 React-Native 和 Flutter 该怎么选? 在 10 个月前的 MWC 上,谷歌发布了 Flutter 的 Beta 版本,给跨平台应用开发带来了一种全新的选择,昨天谷歌正式 ...

  6. Leetcode 102 二叉树的层次遍历 Python

    二叉树的层次遍历 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15,7],   3   / \ 9 20 ...

  7. VS中工程的“依赖”,“库目录”,“包含目录”

    写多了Vs中的工程,就会遇到很多环境配置问题,例如“依赖项”,“库目录”,“包含目录”等等等等. 今天要记录的就是这些的基本含义:我们拿一个例子来看,更加清晰易懂一些: 例如在Opencv3.0+VS ...

  8. Access to the path ‘’ is denied

    2019/4/29 问题:利用VS实现数据导出,出现Error:Access to the path 'F:\HPYMTotalCode\Web\dd\xmqjd.xls' is denied. 原因 ...

  9. Django分页类的封装

    Django分页类的封装 Django ORM  封装 之前有提到(Django分页的实现)会多次用到分页,将分页功能封装起来能极大提高效率. 其实不是很难,就是将之前实现的代码全都放到类中,将需要用 ...

  10. mysql启动不起来

    在刚编译安装完成mysql,启动mysql时报了下面错误: /etc/init.d/mysqld start Starting MySQL... ERROR! The server quit with ...