`
Aga
  • 浏览: 218612 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

利用commons-digester解析xml

阅读更多
jakarta的commons中的digester是非常优秀的xml解析工具,这个工具提供了从
xml->javabean的映射。相较于传统的w3c、sax方式解析xml文档,digester的层次更高,适合更懒得家伙。
下面这个例子简单,就是一个简单的存储数据,xml文件由schema文件约束,映射到对应的javabean当中,当然功能还不是很完善,作用也不够通用。
schema文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://www.example.org/final"
	xmlns:tns="http://www.example.org/final"
	elementFormDefault="qualified">

	<element name="doc">
		<complexType>
			<sequence>
				<element name="prvs" type="tns:prvs-type" />
				<element name="usrs" type="tns:usrs-type" />
			</sequence>
		</complexType>
	</element>

	<complexType name="prvs-type">
		<sequence>
			<element name="prv" minOccurs="0" maxOccurs="unbounded"
				type="tns:prv-type" />
		</sequence>
	</complexType>

	<complexType name="usrs-type">
		<sequence>
			<element name="usr" minOccurs="0" maxOccurs="unbounded"
				type="tns:usr-type" />
		</sequence>
	</complexType>

	<complexType name="prv-type">
		<sequence>
			<element name="name" type="string" />
			<element name="descr" type="string" />
		</sequence>
		<attribute name="prv_id" type="integer" use="required" />
	</complexType>

	<complexType name="usr-type">
		<sequence>
			<element name="name" type="string" />
			<element name="pwd" type="string" />
			<element name="prvs">
				<complexType>
					<sequence>
						<element name="prv_id" type="integer"
							minOccurs="0" maxOccurs="unbounded" />
					</sequence>
				</complexType>
			</element>
		</sequence>
		<attribute name="usr_id" type="integer" use="required" />
	</complexType>
</schema>

对应2个具体的javabean:
一个是user类,代码如下:
package com.cxz.xmldb;

import java.util.HashSet;
import java.util.Set;
import java.util.Collections;

public class User {
	private int usr_id;

	private String name;

	private String pwd;

	private Set<Integer> prvs_id = Collections
			.synchronizedSet(new HashSet<Integer>());

	private Set<Privilege> prvs = Collections
			.synchronizedSet(new HashSet<Privilege>());

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getUsr_id() {
		return usr_id;
	}

	public void setUsr_id(int usr_id) {
		this.usr_id = usr_id;
	}

	public void addPrv(Privilege priv) throws DuplicateException {
		if (!prvs.add(priv))
			throw new DuplicateException(
					"The privilege had been duplicated created.");
	}

	public void rmvPrv(Privilege priv) {
		prvs.remove(priv);
	}

	public void addPrvId(Integer priv) throws DuplicateException {
		if (!prvs_id.add(priv))
			throw new DuplicateException(
					"The privilegeId had been duplicated created.");
	}

	public void rmvPrvId(Integer priv) {
		prvs_id.remove(priv);
	}

	public Set<Privilege> getPrvs() {
		return prvs;
	}

	public void setPrvs(Set<Privilege> prvs) {
		this.prvs = prvs;
	}

	public Set<Integer> getPrvs_id() {
		return prvs_id;
	}

	public void setPrvs_id(Set<Integer> prvs_id) {
		this.prvs_id = prvs_id;
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + usr_id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final User other = (User) obj;
		if (usr_id != other.usr_id)
			return false;
		return true;
	}

}

另一个类是privilege类:
package com.cxz.xmldb;

public class Privilege {
	private int prv_id;

	private String name;

	private String descr;

	public String getDescr() {
		return descr;
	}

	public void setDescr(String descr) {
		this.descr = descr;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrv_id() {
		return prv_id;
	}

	public void setPrv_id(int prv_id) {
		this.prv_id = prv_id;
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + prv_id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Privilege other = (Privilege) obj;
		if (prv_id != other.prv_id)
			return false;
		return true;
	}
}

下面这个是xml数据文件,包括了具体的关系:
<?xml version="1.0" encoding="UTF-8"?>
<doc xmlns="http://www.example.org/final"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.example.org/final doc.xsd ">
	<prvs>
		<prv prv_id="0">
			<name>read</name>
			<descr>read the file</descr>
		</prv>
		<prv prv_id="1">
			<name>write</name>
			<descr>write the file</descr>
		</prv>
		<prv prv_id="2">
			<name>execute</name>
			<descr>execute the file</descr>
		</prv>
	</prvs>
	<usrs>
		<usr usr_id="2003710201">
			<name>cxz</name>
			<pwd>19841230</pwd>
			<prvs>
				<prv_id>0</prv_id>
				<prv_id>1</prv_id>
				<prv_id>2</prv_id>
			</prvs>
		</usr>
		<usr usr_id="2003710202">
			<name>wm</name>
			<pwd>19841230</pwd>
			<prvs>
				<prv_id>0</prv_id>
				<prv_id>1</prv_id>
			</prvs>
		</usr>
		<usr usr_id="2003710203">
			<name>wjt</name>
			<pwd>19841230</pwd>
			<prvs>
				<prv_id>1</prv_id>
				<prv_id>2</prv_id>
			</prvs>
		</usr>
	</usrs>
<!--
	<ulist>
		yxiong = role,role2...
		ben = role2
	</ulist>
	
	<pri>
		role = a.jsp,b.action,....
	</pri>
 -->		
</doc>

这个类代表了整个文档
package com.cxz.xmldb;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Document {
	private Set<Privilege> prvs = Collections
			.synchronizedSet(new HashSet<Privilege>());

	private Set<User> usrs = Collections.synchronizedSet(new HashSet<User>());

	public Document() {
	}

	public void addPrivilege(Privilege p) throws DuplicateException {
		if (!prvs.add(p))
			throw new DuplicateException("Duplicated Priv");
	}

	public void removePrivilege(Privilege p) {
		prvs.remove(p);
	}

	public void addUser(User u) throws DuplicateException {
		if (!usrs.add(u))
			throw new DuplicateException("Duplicated Usr");
	}

	public void removeUser(User u) {
		usrs.remove(u);
	}

	public void fetch() throws DuplicateException, Exception {
		for (User usr : usrs) {
			for(Integer prvId : usr.getPrvs_id()){
				usr.addPrv(this.getOnePriv(prvId.intValue()));
			}
		}
	}
	
	private Privilege getOnePriv(int prvId) throws Exception{
		for(Privilege priv: prvs){
			if(priv.getPrv_id() == prvId)
				return priv;
		}
		throw new Exception("I didn't find the privilege entity.");
	}
}

最后就是一个装配类,这个才是整个项目的重头:安装rule,从而建立映射关系。从而达到xml->javabean的映射。一个user对应多个privilege,类似于hibernate的映射:应该有一个容器,装载了所有的这个user实例所对应的privilege对象,当然,我采用的方法类似hibernate也是先装载一个id主,然后调用Document.fetch()进行填充,把id转化为具体的实例。
package com.cxz.xmldb;

import java.io.IOException;

import org.apache.commons.digester.CallMethodRule;
import org.apache.commons.digester.CallParamRule;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.ObjectCreateRule;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.SetNextRule;
import org.apache.commons.digester.SetPropertiesRule;
import org.xml.sax.SAXException;

public class SimpleDigester {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws DuplicateException 
	 */
	public static void main(String[] args) throws DuplicateException, Exception {
		Digester digester = new Digester();

		Rule docCreate = new ObjectCreateRule("com.cxz.xmldb.Document");
		digester.addRule("doc", docCreate);

		Rule prvCreate = new ObjectCreateRule("com.cxz.xmldb.Privilege");
		digester.addRule("doc/prvs/prv", prvCreate);

		Rule usrCreate = new ObjectCreateRule("com.cxz.xmldb.User");
		digester.addRule("doc/usrs/usr", usrCreate);

		Rule propertiesSet = new SetPropertiesRule();
		digester.addRule("doc/prvs/prv", propertiesSet);
		digester.addRule("doc/usrs/usr", propertiesSet);

		digester.addRule("doc/prvs/prv", new SetNextRule("addPrivilege"));
		digester.addRule("doc/usrs/usr", new SetNextRule("addUser"));

		// digester.addRule("doc/prvs/prv", new CallMethodRule("setDescr", 1,
		// new Class[] { String.class }));
		// digester.addRule("doc/prvs/prv/descr", paramRule);
		//		
		// digester.addRule("doc/prvs/prv", new CallMethodRule("setName", 1,
		// new Class[] { String.class }));
		// digester.addRule("doc/prvs/prv/name", paramRule);

		digester.addRule("doc/prvs/prv/name", new CallMethodRule("setName", 0,
				new Class[] { String.class }));

		digester.addRule("doc/prvs/prv/descr", new CallMethodRule("setDescr",
				0, new Class[] { String.class }));

		digester.addRule("doc/usrs/usr/name", new CallMethodRule("setName", 0,
				new Class[] { String.class }));

		digester.addRule("doc/usrs/usr/pwd", new CallMethodRule("setPwd", 0,
				new Class[] { String.class }));

		digester.addRule("doc/usrs/usr/prvs/prv_id", new CallMethodRule(
				"addPrvId", 0, new Class[] { Integer.class }));

		Document doc = (Document) digester.parse(SimpleDigester.class
				.getClassLoader().getResource("doc.xml"));
		
		doc.fetch();

	}

}
7
3
分享到:
评论
2 楼 Aga 2008-07-23  
多谢提醒,
不过xstream和digester那个更好呢?
似乎digester不能进行javabean->xml的映射。
1 楼 linginfanta 2008-07-23  
用Xstream

相关推荐

    commons-digester-2.1.jar

    Apache Commons Digester库提供了一种规则驱动的方法来解析XML文档,并根据预定义的规则将XML数据映射到Java对象上。这个库在处理XML配置文件时特别有用,它允许开发者将XML结构转换为相应的Java对象结构,从而简化...

    commons-digester.jar

    `commons-digester.jar`是Apache Commons项目中的一个组件,主要功能是解析XML文档并根据预定义的规则自动创建和填充Java对象。这个组件在Java应用程序中尤其有用,特别是那些需要从XML配置文件中构建复杂对象层次...

    commons-digester-1.7.jar.zip

    《Apache Commons Digester 1.7:解析XML的利器》 Apache Commons Digester是一个Java库,主要用于解析XML文档,并根据预定义的规则将其转换为Java对象。在标题和描述中提到的"commons-digester-1.7.jar.zip"是一个...

    commons-digester-2.0.rar源文件及jar文件

    《Apache Commons Digester 2.0:解析XML的利器》 Apache Commons Digester是一个Java库,主要用于将XML文档解析成Java对象。这个库的核心功能是根据预定义的规则(Rule)来读取XML文档,然后根据这些规则进行一...

    commons-digester源码

    **Apache Commons Digester** 是一个Java库,它允许开发人员定义一套规则,这些规则可以解析XML文档,并根据这些规则在Java对象模型中创建和配置对象。这个库在处理XML到Java对象映射时非常有用,特别是在构建配置...

    xml解析commons-digester的demo

    这个示例演示了如何使用Apache Commons Digester解析XML文件,将XML数据转换为Java对象。通过定义规则,我们可以轻松地处理复杂的XML结构,并将它们映射到Java对象模型中。这在处理大量配置数据或需要从XML文件加载...

    commons-digester.jar下载

    Commons-Digester是一个Java库,它提供了一组规则来解析XML文档,并将解析结果映射到Java对象。这个库在处理XML配置文件时特别有用,因为它可以自动化将XML元素和属性转换为对象的属性和方法调用。在给定的标题...

    commons-digester-1.7.zip

    Commons Digester是一个强大的Java库,它允许开发人员根据XML文档中的模式规则来创建和操作对象。这个"commons-digester-1.7.zip"文件包含了Apache Commons Digester库的1.7版本,这是一个广泛用于处理XML到Java对象...

    quartz-1.6.0/commons-beanutils/commons-digester-1.7 JAR包

    Digester提供了一种从XML文档创建Java对象结构的方式,它可以根据预定义的规则集(RuleSet)自动解析XML,并调用相应的JavaBean方法,实现XML到Java对象的映射。这个库特别适用于那些XML配置文件需要转化为Java对象...

    commons-digester-2.0.jar.zip

    Apache Commons Digester是一个强大的Java库,主要功能是解析XML文档,并根据预定义的规则将其转换为Java对象。在标题"commons-digester-2.0.jar.zip"中,我们看到的是这个库的一个特定版本——2.0,它被压缩成一个...

    commons-digester-2.1.jar.zip

    3. **Digest Process**:Digester解析XML文档的过程,按照规则集执行,将XML结构转化为Java对象。 ## 三、主要功能 1. **对象创建**:根据XML元素创建对应的Java对象。例如,每当解析到特定的XML标签时,可以创建...

    commons-digester.jar commons-dbcp.jar

    通过定义一系列规则,你可以控制如何将XML元素映射到Java对象的属性,这样就可以避免手动解析XML并创建对象的繁琐过程。 接下来,`commons-dbcp-1.2.2.jar`是Apache Commons Database Connection Pooling(DBCP)的...

    commons-digester-1.8-src 下载 struts源码 digester

    这个开源库是Java开发人员常用的一个工具,它允许程序通过定义规则来解析XML文档,并根据这些规则进行对象的创建和属性设置。这在构建基于XML配置的系统,如Struts框架时特别有用。 Apache Commons Digester是一个...

    commons-digester-2.0.jar

    digester必备的jar,XML解析专用

    commons-digester-2.0-bin

    在实际应用中,Commons Digester常用于配置文件的解析,例如在Spring框架中,它被用来解析XML配置文件,创建和配置bean。此外,它也适用于任何需要根据XML结构动态生成和操作Java对象的场景。 总的来说,Commons ...

    org.apache.commons.digester解析XML.rar

    这个“org.apache.commons.digester解析XML.rar”压缩包包含了一个测试工程,它演示了如何使用Digester库来解析XML文件并映射到Java对象上。下面将详细介绍这个库的功能、使用方法以及在实际开发中的应用。 1. **...

Global site tag (gtag.js) - Google Analytics