digester解析xml生成对象

解析xml的工具有很多种:dom,dom4j,sax, Digester底层是使用的sax

一、引用 jar包

  • commons-digester.jar
  • commons-beanutils-1.7.0.jar
  • commons-logging-1.1.jar

二、要读取的xml

<?xml version="1.0" encoding="utf-8" ?>
<school>
    <classes> 
        <grade className="classOne" teacher="小花老师">
            <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>
        </grade> 
       
    </classes>
</school>

三、代码实现

1、思路:最终目的是要创建3个Student和一个grade对象,先写bean对象,解析的时候默认对象属性和xml里面的标签是对应 的,如果不一致需要显示的标明:digester.addBeanPropertySetter("school/classes/grade/student/no","id");

2、代码:

public class Student {
	private int id ;
	private String name;
	private int age;
	
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

public class Grade {
	private String className;
	private String teacher;
	private List<Student> Students = new ArrayList<Student>();
	
	public void addStudent(Student student){
		 Students.add(student);
	}
	 

	@Override
	public String toString() {
		return "Grade [className=" + className + ", teacher=" + teacher
				+ ", Students=" + Students + "]";
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	public List<Student> getStudents() {
		return Students;
	}
	public void setStudents(List<Student> students) {
		Students = students;
	}
}

public class Digester1 {
	  
	private Grade grade;
	private SystemConfig systemConfig;
	
	public static void main(String[] args) {
		Digester1 digester1 = new Digester1();
		digester1.loadConfig(); 
		System.out.println(digester1.grade);
		System.out.println(digester1.systemConfig);
	}
	private Digester digester;
	public void loadConfig(){
		//1.建立一个digester对象
		digester = new Digester();
		//应该是预防此对象加载 多个
		digester.setClassLoader(Thread.currentThread().getContextClassLoader());
		//将当前对象入到栈底,做为基准对象,下面第一个addSetNext() 这里面反射用到是引对象的方法
		digester.push(this);
		//2、不用dtd验证xml文档的合法性,我们没有为xml文档定义dtd
		digester.setValidating(false);
		
		//3.1从school--classes-class
		final String gradeXml = "school/classes/grade";
		//4.1将className赋值给对象
		digester.addObjectCreate(gradeXml, Grade.class);
		digester.addSetProperties(gradeXml); 
		digester.addSetNext(gradeXml, "addGrade");//这里面调用的是上个节点的方法,也就是Digester的方法
 
		
		//3、从school--classes--class--student
		final String stuXml= "school/classes/grade/student";
		digester.addObjectCreate(stuXml,Student.class);
		//4、将no,name,age标签赋给对象 
        digester.addBeanPropertySetter(stuXml+"/no","id");//将no里面数据放到Student的id字段中
        digester.addBeanPropertySetter(stuXml+"/name");
        digester.addBeanPropertySetter(stuXml+"/age");
        
        digester.addSetNext(stuXml, "addStudent"); //这里调用的是前面被实例化的类,也就是grade里面的方法
        
      
		//5、解析xml文件
		try { 
			digester.parse(new File("./config/test1.xml"));
		} catch (IOException | SAXException e) { 
			e.printStackTrace();
		}
	}
	
	public void addGrade(Grade grade){
		this.grade = grade;
	}
	 
	 
}

3、梳理

digester的使用方法已经在Digester1里面注释的很清楚了,

  • digester解析出来的类是在哪里??

答:如果只是创建一个student对象时,可以使用:Student student = digester.parse(new File("./config/test1.xml"));  

  • addSetNext,这个的作用是什么?

答:如上有多个Student对象需要生成,就需要触发父结点一个方法来储存这些对象,student的父节点是Grade类,Grade创建的对象的父节点是school我这里没用使用,可以忽略,但是Grade对象怎么保存呢???

digester.push(this); 将当前对象压到栈底,创建第一个对象,会调用栈底里面addSetNext里面映射的方法来处理生成的对象

  • 如果是生成配置对象的话,建议把键值对写到xml标签的属性中,只需要一句代码就会自动将属性里面的键值对入到对象中,digester.addSetProperties(gradeXml);   会解析className,teacher
  • 下面是怎么将方法设置到对象中 引用 : https://blog.csdn.net/shang02/article/details/53258904

addCallMethod(String rule,String methodName,int paraNumber)

该方法同样设置对象的属性,但更加灵活,不需要对象具有setter

根据rule规则指定的属性,调用对象的methodName方法,paraNumber参数是表示方法需要的参数个数,当paraNumber=0时,可以单独使用,不然需要配合addCallParam方法

比如:digester.addCallMethod("database/user/userName","setUserName",0), 参数为xml当前值;无参方法:digester.addCallMethod( "pattern", "methodName" );.

addCallParam(String rule,int paraIndex,String attributeName)

该方法与addCallMethod配合使用,根据rule指定的标签属性来调用方法

paraIndex表明需要填充的方法形参序号,从0开始,方法由addCallMethdo指定,attributeName指定标签属性名;

使用注意事项:
   1.Digester类调用的顺序,必须与XML数据文件绝对一致;
   2.Digester类依赖于JavaBean规范,类必须符合规范;
   3.XML文件中标签/属性的名称必须与Bean中的一致(包括大小写)

;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值