`
Aga
  • 浏览: 214172 次
  • 性别: 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

相关推荐

    xml解析commons-digester的demo

    xml解析commons-digester的demo

    commons-digester-2.0.jar

    digester必备的jar,XML解析专用

    digester解析xml必备包.rar

    digeter解析xml所必须的jar包,包括commons-logging-1.2.jar、commons-digester-2.1.jar、commons-beanutils-1.9.3.jar

    Commons-digesterXML解析Demo

    Commons-digesterXML解析Demo,一个小例子,对于新人来说,绝对是一个实用的小Demo..

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

    org.apache.commons.digester解析XML.rar 完整的测试工程,里面有需要的四个包

    Jakarta-Common-Digester使用笔记

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

    apache-commons源码及jar文件

    Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件. Discovery Commons-Discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。. EL Commons-EL 提供在...

    使用digester解析XML

    不错的解析XML的类,主要利用org.apache.commons.digester.Digester;

    用到digester项目,直接解析存入数据库

    解析使用的xml文件在"参与者基础数据-4月.zip",sql语句就不贴了,如果是测试digester只需将dao层改一下,不要连接数据库,不同数据库创表好麻烦,如果需要存入数据库可以自行创建。

    比较全面的:Jakarta-commons jar包(附: chm参考手册 & 资源简介)

    commons-digester XML 文件到 Java 对象的映射机制 commons-discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。 commons-el 提供在JSP2.0规范中定义的EL表达式的解释器. ...

    Jakarta commons docs API CHM 格式

    commons-digester XML 文件到 Java 对象的映射机制 commons-discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。 commons-el 提供在JSP2.0规范中定义的EL表达式的解释器. ...

    OSChina 所有jar

    7 commons-digester-2.0.jar XML解析,Velocity依赖 8 commons-email-1.2.jar 邮件发送包 9 commons-httpclient-3.1.jar HTTP客户端 10 commons-io-1.4.jar IO处理包 11 commons-lang-2.4.jar 语言处理包 12 ...

    框架中常用的jar包作用

    Digester基于规则的XML文档解析,主要用于XML到Java对象的映射. commons-beanutils.jar 提供对Java 反射和自省API的包装. aspectjweaver.jar 用于在Spring 2.0中集成AspectJ AspectJ LTW织入器 ognl.jar OGNL是...

    开发自己一套struts框架

    此项目是为了更深入的理解MVC模式以及Struts的工作流程而开发的,运用了第三方commons组件, commons-digester来解析xml文件,把配置信息全部封装成类,然后运用MVC的思想去做相应的操作.

    web开发常用jar

    Apache Commons包中的一个,通过它可以很方便的解析xml文件生成java对象 aspectjrt.jar 和aspectjweaver.jar Annotation 方式实现 AOP commons-dbcp.jar commons-pool-1.2.jar DBCP数据库连接池 cglib-nodep...

    java开发常用jar包

    Apache Commons包中的一个,通过它可以很方便的解析xml文件生成java对象 aspectjrt.jar 和aspectjweaver.jar Annotation 方式实现 AOP commons-dbcp.jar commons-pool-1.2.jar DBCP数据库连接池 cglib-nodep-2.1_...

Global site tag (gtag.js) - Google Analytics