论坛首页 Java企业应用论坛

Digester解析xml笔记

浏览 4645 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-07-31   最后修改:2009-07-31
最近项目里用到Digester,查阅了网上好多资料,仔细的研究了下,作下笔记,供日后参考。

需要解析的xml如下:

<?xml version='1.0' encoding='utf-8'?>

<persons>
	<person name="tom">
		<age>4</age>
		<address>
			<street>no1street</street>
			<belongarea>us</belongarea>
		</address>
		<creditcard>
			<limit code="123" pwd="abc">1000</limit>
			<bank>ICBC</bank>
		</creditcard>
		<creditcard>
			<limit code="321" pwd="cba">2000</limit>
			<bank>CBC</bank>
		</creditcard>
	</person>
	<person name="jerry">
		<age>5</age>
		<address>
			<street>no2street</street>
			<belongarea>us</belongarea>
		</address>
	</person>
</persons>


解析代码如下:(Bean就不贴了,见附件src。)运行此代码需要apache.commons下的4个jar包分别为:collections,digester,logging,beanutils

package com.young;

import java.io.File;
import java.io.IOException;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

import com.young.bean.Address;
import com.young.bean.Creditcard;
import com.young.bean.Person;
import com.young.bean.Root;

/**
 * @author yang
 * @date 2009-7-30
 */
public class DigesterTest {
	
	/**
	 * Digester 支持直接抓取url上的xml
	 * new Digester().parse(String url);
	 */
	void parseByDigester(File f) throws IOException, SAXException{
		Digester d=new Digester();
		//不进行dtd校验
		d.setValidating(false);

		/** 
		 * push:将一个根节点对象压入栈。
		 * 以下2个方法二者用其一即可,不过后者具有局限性(可以通过测试感受一下),推荐使用push的形式
         */
		d.push(new Root());
		//d.addObjectCreate("person",Root.class);
		
		d.addObjectCreate("persons/person", Person.class);
		/**
		 * 	对应xml:
		 * 	<person name="tom">
		 *	 <age>4</age>
		 *	 ...
		 *	</person>
		 *  
		 *	setProperties 用来操作Attribute
		 *	setBeanPropertySetter 用来操作Node
		 *	xml和bean参数一致的情况下可以这样写
		 *  d.addSetProperties("persons/person");
		 */
		d.addSetProperties("persons/person","name","name");
		d.addBeanPropertySetter("persons/person/age");
		
		/**
		 * 	对应xml:
		 * 	<address>
		 *	 <street>no1street</street>
		 *	 <belongarea>us</belongarea>
		 * 	</address>
		 * 
		 *  自定义对象务必要有这一句:
		 *  d.addSetNext("persons/person/address", "setAddress");
		 */
		d.addObjectCreate("persons/person/address", Address.class);
		d.addBeanPropertySetter("persons/person/address/street");
		d.addBeanPropertySetter("persons/person/address/belongarea","belongArea");
		d.addSetNext("persons/person/address", "setAddress");
		
		/**
		 *  对应xml:
		 *  <creditcard>
		 *   <limit code="123" pwd="abc">1000</limit>
		 *   <bank>ICBC</bank>
		 *  </creditcard>
		 *  
		 *  addCallMethod()调用指定方法,第三个参数为参数个数,对应下面的addCallParam的第二个参数
		 *  addSetProperties()参数不对应情况的写法
		 */
		d.addObjectCreate("persons/person/creditcard",Creditcard.class);
		d.addCallMethod("persons/person/creditcard", "setParas", 2);
		//参数不一致 TODO 第三个参数 attributeName 需要查阅api
		d.addCallParam("persons/person/creditcard/limit", 0);
		d.addCallParam("persons/person/creditcard/bank", 1);

		d.addSetProperties("persons/person/creditcard/limit");
		d.addSetProperties("persons/person/creditcard/limit","pwd","passwd");
		d.addSetNext("persons/person/creditcard", "addCreditcard");

		/**
		 * addSetNext():当在遇到"persons/person"此节点的是很调用addPersons()方法,第三个参数为该方法的ParameterType。
		 * 注意:addPersons方法需要为public,曾经因为这个问题调试了好久找不到问题所在!
		 */
		d.addSetNext("persons/person", "addPersons",Person.class.getName());
		
		Root r=(Root)d.parse(f);
		
		System.out.println(r);
	}

	public static void main(String[] args) throws IOException, SAXException{
		DigesterTest test=new DigesterTest();
		test.parseByDigester(new File("D:\\workbench\\DigesterInAction\\src\\person.xml"));
	}
}



特别注意:addPersons方法需要public的问题,困扰了我1个多小时,就是找不到原因!!

Digester的标准规则:


1. 创建规则(Creational)
对象创建规则(ObjectCreateRule): 
    根据指定类和它的默认构造方法创建一个对象,并将其压栈。当这个结点处理完后,并这个对象弹出。这个类可以通过类对象或类的全名进实例化。 工厂创建规则(FactoryCreateRule): 
    使用指定的工厂类创建一个对象,并将其压栈。这个类没有默认的构造方法的工厂类是非常有用的。这个工厂类必须实现org.apache.commons.digester.ObjectCreationFactory接口。

2. 属性设置规则(Property Setters)
SetPropertiesRule: 
    使用指定的XML结点属性来设置栈的顶层bean的一个或多个属性。属性名通过String[]数组传递,如处理象<article page="30">的XML指令。

BeanPropertySetterRule: 
    通过当前XML结点的字符串值设置栈顶对象的属性,如<page>30</page>。

SetPropertyRule: 

    这个规则设置一个最顶层的对象的属性,需要有两个值,key和value。如<article key="page" value="10" />。

3. 父 / 子管理规则(Parent/Child Management)
SetNextRule: 
    弹出最顶层的对象,并将它传递给这个对象下面的指定的方法。类似将子结点插入到父结点的下面。

SetTopRule: 
    将栈的第二个对象传给顶层对象。这对于当子对象有一个setParent方法而不是其他方法时非常有用。

SetRootRule: 

    调用栈底部对象的一个方法,并将顶层对象作为一个参数传入。 

4. 调用任意方法
CallMethodRule: 
    调用最顶层bean的指定的任意方法。这个方法可以有任意个参数。参数值通过CallParamRule给出。

CallParamRule: 

    描述方法参数的值。参数值或者是XML结点的属性值,或是XML结点的字符串内容值。这个规则要求参数的位置必须由一个整数索引指定。



  • src.rar (3.4 KB)
  • 下载次数: 398
   发表时间:2009-12-08   最后修改:2009-12-08
比较清楚 配合教学视频清楚多了
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics