Digester解析xml笔记

最近项目里用到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>


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

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"));
}
}



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

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结点的字符串内容值。这个规则要求参数的位置必须由一个整数索引指定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值