利用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();

}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值