`
prowl
  • 浏览: 80853 次
  • 性别: Icon_minigender_1
  • 来自: 艾泽拉斯
社区版块
存档分类
最新评论

Digester解析xml笔记

    博客分类:
  • 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>


解析代码如下:(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
分享到:
评论
2 楼 li370036149 2013-10-09  
很详细
1 楼 dongguojun 2009-12-08  
比较清楚 配合教学视频清楚多了

相关推荐

    Digester读取XML学习

    1. Digester:Apache Commons Digester库的核心,负责解析XML并调用Java方法。 2. XML解析:理解XML文档结构,以及如何使用DOM、SAX或StAX解析器。 3. Java对象绑定:将XML元素映射到Java对象的属性和方法。 4. 规则...

    Jakarta-Common-Digester使用笔记

    我们无须了解SAX和DOM的解析过程,只要给Digester添加一些解析规则,就能对一个xml文件进行解析。Digester使用堆栈来保存xml节点(stack.push()方法),当该xml节点中嵌套的所有子节点解析完毕,该节点将被弹出...

    digester学习笔记

    4. **解析XML**:最后,使用`digester.parse()`方法解析XML文档,完成后,栈顶的对象通常是解析结果的根节点。 在提供的示例中,有两个JavaBean,Foo和Bar。Foo有一个名为addBar的方法,用于添加Bar对象,而Bar包含...

    struts学习的一点笔记

    - **detail**:控制Digester的调试级别,Digester是Struts框架内部用于解析XML配置文件的组件,该参数也影响日志的详细程度。 ### 配置欢迎文件 在Web.xml中配置欢迎文件,可以让用户在访问应用根目录时自动加载...

    commons-digest笔记

    虽然与Digest库的核心散列功能没有直接关系,但它们都是Apache Commons项目的一部分,通常一起使用,以在解析XML时实现更复杂的逻辑和数据验证。 四、应用实例 1. 文件完整性检查:在下载大文件后,通过计算本地...

    apache commons笔记1

    8. **Digester**:提供了 XML 到 Java 对象的映射,通常用于解析 XML 配置文件,简化 XML 数据的处理。 9. **Email** 库:使开发者能从 Java 应用程序发送电子邮件,支持多种邮件协议和附件。 10. **Exec** API:...

    velocity学习笔记与struts2整合

    3. commons-digester-1.8.jar - 解析XML配置文件的库。 4. commons-lang-2.1.jar - 常用的Java语言工具包。 5. velocity-1.5.jar - Velocity核心库。 6. velocity-tools-1.4.jar - 提供Velocity的工具支持。 7. ...

    一个简单的jsf例子------JSF2学习笔记1

    - `commons-digester-2.0.jar` 用于解析XML文档,常在配置或初始化过程中使用。 - `commons-logging-1.1.1.jar` 是一个通用的日志抽象层,允许选择不同的日志实现。 - `jstl.jar` 包含JSTL (JavaServer Pages ...

Global site tag (gtag.js) - Google Analytics