`
lancijk
  • 浏览: 388341 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

org.apache.commons.digester.Digester 解析 XML文件或者流

    博客分类:
  • Java
 
阅读更多

最近在做快捷支付这块,对XML这块接触的比较多.梳理XML这块的时候, 突然发现 Digester 对不管是 字符串的 XML 还是 XML文件都能很好的解析..不足点就是引用的 apache的东西有点多. (apache的东西 耦合性太高.....)不过确实好用..

 

首先是 import

 

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSetBase;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
 

 

这几个是主要的..至于还有其他的可以自己再加入.

 

 

一 : 然后是主方法(分两个,一个是 文件.  一个是 string字符串)

 

1:首先看 读取文件的主方法, 一些解释的话 可以上这个地址

http://onjava.com/pub/a/onjava/2002/10/23/digester.html?page=2 查看

 

	public static void testXML1() throws ParseException{
		File inputStream = new File("c:/jack/test.xml");
		Digester configDigester = new Digester();
	    configDigester.setNamespaceAware(true);
	    configDigester.setValidating(false);
	    configDigester.setUseContextClassLoader(true);
	    //load rule set
	    configDigester.addRuleSet(new PaymentStatusCheckResponseRuleSet());
	    OrderCheckResponseConfig datas = new OrderCheckResponseConfig();
	    configDigester.push(datas);
	    try {
			configDigester.parse(inputStream);
		} catch (IOException e) {
			e.printStackTrace();
			throw new ParseException(e);
		} catch (SAXException e) {
			e.printStackTrace();
			throw new ParseException(e);
		}
		 Map responseProp = new HashMap();

	        responseProp.put("status", datas.getStatus());
	        responseProp.put("statusText", datas.getStatusText());
	        responseProp.put("msgCode", datas.getMsgCode());
	        responseProp.put("msgCn", datas.getMsgCn());
	        responseProp.put("orderDate", datas.getOrderDate());
	        responseProp.put("orderTime", datas.getOrderTime());
	        responseProp.put("orderNo", datas.getOrderNo());
	        responseProp.put("orderAmt", datas.getOrderAmt());
	        responseProp.put("currId", datas.getCurrId());
	        responseProp.put("payAmt", datas.getPayAmt());
	        responseProp.put("memo", datas.getMemo());
	        responseProp.put("payNo", datas.getPayNo());
	        responseProp.put("hostDate", datas.getHostDate());
	        responseProp.put("accNo", datas.getAccNo());
	        responseProp.put("hoistTime", datas.getHoistTime());
	        responseProp.put("accType", datas.getAccType());
	        responseProp.put("pbCstName", datas.getPbCstName());
	   System.out.println(responseProp);
	}

 

 

addRuleSet , 可以写一个内部的  RuleSet 类,主要是用来读取XML的节点信息和内容的

 

 

 

/**
 * Inner class for StatusCheckResponse ruleset
 */
class PaymentStatusCheckResponseRuleSet extends RuleSetBase{
	public void addRuleInstances(Digester digester) {
        
		digester.addCallMethod("stream/status", "setStatus", 1);
        digester.addCallParam("stream/status", 0);
        
        digester.addCallMethod("stream/statusText", "setStatusText", 1);
        digester.addCallParam("stream/statusText", 0);
        
        digester.addCallMethod("stream/msgCode", "setMsgCode", 1);
        digester.addCallParam("stream/msgCode", 0);
        
        digester.addCallMethod("stream/msgCn", "setMsgCn", 1);
        digester.addCallParam("stream/msgCn", 0);
        
        digester.addCallMethod("stream/orderDate", "setOrderDate", 1);
        digester.addCallParam("stream/orderDate", 0);
        
        digester.addCallMethod("stream/orderTime", "setOrderTime", 1);
        digester.addCallParam("stream/orderTime", 0);
        
        digester.addCallMethod("stream/orderNo", "setOrderNo", 1);
        digester.addCallParam("stream/orderNo", 0);
        
        digester.addCallMethod("stream/orderAmt", "setOrderAmt", 1);
        digester.addCallParam("stream/orderAmt", 0);
        
        digester.addCallMethod("stream/currId", "setCurrId", 1);
        digester.addCallParam("stream/currId", 0);
        
        digester.addCallMethod("stream/payAmt", "setPayAmt", 1);
        digester.addCallParam("stream/payAmt", 0);
        
        digester.addCallMethod("stream/memo", "setMemo", 1);
        digester.addCallParam("stream/memo", 0);
        
        digester.addCallMethod("stream/payNo", "setPayNo", 1);
        digester.addCallParam("stream/payNo", 0);
        
        digester.addCallMethod("stream/hostDate", "setHostDate", 1);
        digester.addCallParam("stream/hostDate", 0);
        
        
        digester.addCallMethod("stream/hoistTime", "setHoistTime", 1);
        digester.addCallParam("stream/hoistTime", 0);
        
        digester.addCallMethod("stream/accNo", "setAccNo", 1);
        digester.addCallParam("stream/accNo", 0);
        
        digester.addCallMethod("stream/accType", "setAccType", 1);
        digester.addCallParam("stream/accType", 0);
        
        digester.addCallMethod("stream/pbCstName", "setPbCstName", 1);
        digester.addCallParam("stream/pbCstName", 0);
        
    }
}
 

 

 

最后就是一个实体的接受类 Digester会push数据进来的(省了 get set 方法)

 

 

public class OrderCheckResponseConfig {
	private String status; //该笔直联查询交易的状态
	private String statusText;//该笔直联查询交易状态的说明
	private String msgCode; //交易状态
	private String msgCn;   //交易状态信息
	private String orderDate;//订单日期
	private String orderTime;//订单时间
	private String orderNo;	//订单号
	private String orderAmt;//订单金额
	private String currId;	//支付币种
	private String payAmt;	//支付金额
	private String memo;	//摘要信息
	private String payNo;	//支付交易流水号
	private String hostDate;//主机操作日期
	private String hoistTime;//主机操作时间
	private String accNo;	//支付卡号
	private String accType;	//卡号类型
	private String pbCstName;//个人消费者中文姓名
 

 

这个 的 XML 比较简单 如下图所示.没有什么复杂的节点.

 

 

<?xml version="1.0" encoding="GBK"?>
<stream>
  <status>1</status><!--该笔直联查询交易的状态char(7) -->
  <statusText>2</statusText><!--该笔直联查询交易状态的说明varchar(254) -->
  <msgCode>交易状态</msgCode><!--该笔订单的交易状态char(7)-->
  <msgCn>交易状态信息</msgCn><!--该笔订单的交易状态的说明varchar(254)-->
  <orderDate>订单日期</orderDate><!--订单日期格式YYYYMMDD-->
  <orderTime>订单时间</orderTime><!--订单时间格式HHmmss-->
  <orderNo>订单号</orderNo><!--char(20)-->
  <orderAmt>订单金额</orderAmt><!--decimal(15,2)-->
  <currId>支付币种</currId><!--char(3)-->
  <payAmt>支付金额</payAmt><!--decimal(15,2)-->
  <memo>摘要信息</memo><!--char(22)-->
  <payNo>支付交易流水号</payNo><!--char(20)-->
  <hostDate>主机操作日期</hostDate><!--日期格式YYYYMMDD-->
  <hoistTime>主机操作时间</hoistTime><!--时间格式HHmmss-->
  <accNo>支付卡号</accNo><!--char(19)-->
  <accType>卡号类型</accType><!--char(2) 02 信用卡 01 借记卡-->
  <pbCstName>个人消费者中文姓名</pbCstName><!--varchar(42)-->
</stream>
 

 

 

 

2:如果是字符串形式的话. 方法如下  (删除了一些, 还需要转变编码格式)

 

 

 

public static void testXML2() throws ParseException{
		String text = "<?xml version=\"1.0\" encoding=\"GBK\"?><stream><status>交易状态</status><!--交易状态 char(7)--><statusText>交易状态信息</statusText><!--交易状态信息 varchar(254)--><batNo></batNo>批次号<!--批次号 varchar(8)--><sucTotalNum>银行受理成功总笔数</sucTotalNum><!--银行受理成功总笔数 int--><sucTotalAmt>银行受理成功总金额</sucTotalAmt><!--银行受理成功总金额 decimal(15,2)--><errTotalNum>银行受理失败总笔数</errTotalNum><!--银行受理失败总笔数int--><errTotalAmt>银行受理失败总金额</errTotalAmt><!--银行受理失败总金额 decimal(15,2)-->" +
				"<list name=\"userDataList\"><row><cancelFlwNo>商户充值退回流水号</cancelFlwNo><!--商户充值退回流水号varchar(20) --><status>liststatus</status><!--交易银行受理状态char(7)--><statusText>liststatusText</statusText><!--交易银行受理状态信息 varchar(254)--></row></list></stream>";
		System.out.println(text);
		
		InputStream inputStream=new ByteArrayInputStream(text..getBytes("gb2312"));//指定编码格式防止乱码

		//File inputStream = new File("c:/jack/refund.xml");
		Digester configDigester = new Digester();
	    configDigester.setNamespaceAware(true);
	    configDigester.setValidating(false);
	    configDigester.setUseContextClassLoader(true);
	    //load rule set
	    configDigester.addRuleSet(new CNCBRefundRuleset());
	    CNCBRefundConfig datas = new CNCBRefundConfig();
	    configDigester.push(datas);
	    try {
			configDigester.parse(inputStream);
		} catch (IOException e) {
			e.printStackTrace();
			throw new ParseException(e);
		} catch (SAXException e) {
			e.printStackTrace();
			throw new ParseException(e);
		}
		 Map responseProp = new HashMap();

	        responseProp.put("status", datas.getStatus());
	        responseProp.put("statusText", datas.getStatusText());
	        
	        responseProp.put("batNo", datas.getStatus());
	        responseProp.put("sucTotalNum", datas.getSucTotalNum());
	        responseProp.put("sucTotalAmt", datas.getSucTotalAmt());
	        responseProp.put("errTotalNum", datas.getErrTotalNum());
	        responseProp.put("errTotalAmt", datas.getErrTotalAmt());
	        responseProp.put("cancelFlwNo", datas.getCancelFlwNo());
	        
	        responseProp.put("liststatus", datas.getListsStatus());
	        responseProp.put("liststatusText", datas.getListstatusText());
	        
	        
	   System.out.println(responseProp);
	}
 

 

设置RuleSet  ,写一个内部类

 

class CNCBRefundRuleset  extends RuleSetBase{
	@Override
	public void addRuleInstances(Digester digester) {
		// TODO Auto-generated method stub
		digester.addCallMethod("stream/status", "setStatus", 1);
        digester.addCallParam("stream/status", 0);
        
        digester.addCallMethod("stream/statusText", "setStatusText", 1);
        digester.addCallParam("stream/statusText", 0);
        
    	digester.addCallMethod("stream/sucTotalAmt", "setSucTotalAmt", 1);
        digester.addCallParam("stream/sucTotalAmt", 0);
        
        digester.addCallMethod("stream/sucTotalNum", "setSucTotalNum", 1);
        digester.addCallParam("stream/sucTotalNum", 0);
        
        digester.addCallMethod("stream/errTotalNum", "setErrTotalNum", 1);
        digester.addCallParam("stream/errTotalNum", 0);
        
        digester.addCallMethod("stream/errTotalAmt", "setErrTotalAmt", 1);
        digester.addCallParam("stream/errTotalAmt", 0);
        
        
        digester.addCallMethod("stream/list/row/cancelFlwNo", "setCancelFlwNo", 1);  //这里的 list 也可以用name 来表示.结果是一样的
        digester.addCallParam("stream/list/row/cancelFlwNo", 0);
        
        digester.addCallMethod("stream/list/row/status", "setListsStatus", 1);//以后不管子节点有多少,从最开始往下取,这样就很方便的解析了.
        digester.addCallParam("stream/list/row/status", 0); 
        
        digester.addCallMethod("stream/list/row/statusText", "setListstatusText", 1);
        digester.addCallParam("stream/list/row/statusText", 0);
	}
	
}
 

 

实体bean 

 

 

class CNCBRefundConfig{
	private String status;
	private String statusText;
	private String batNo;
	private String sucTotalNum;
	private String sucTotalAmt;
	private String errTotalNum;
	private String errTotalAmt;
	private String cancelFlwNo;
	private String listsStatus; //如果有重名的,则可以加上list 这个 父节点,区别.  这个就解决了子节点太难读的缺点,可以按照节点路径取值.
	private String liststatusText;
 

 

 

 

 

这个是 XML的 文件形式的.  上面字符串的删除了一些东西. 这个是完整的

 

<?xml version="1.0" encoding="GBK"?>
<stream>
    <status>交易状态</status><!--交易状态 char(7)-->
  <statusText>交易状态信息</statusText><!--交易状态信息 varchar(254)-->
  <batNo></batNo>批次号<!--批次号 varchar(8)-->
  <sucTotalNum>银行受理成功总笔数</sucTotalNum><!--银行受理成功总笔数 int-->
  <sucTotalAmt>银行受理成功总金额</sucTotalAmt><!--银行受理成功总金额 decimal(15,2)-->
  <errTotalNum>银行受理失败总笔数</errTotalNum><!--银行受理失败总笔数int-->
  <errTotalAmt>银行受理失败总金额</errTotalAmt><!--银行受理失败总金额 decimal(15,2)-->
  <list name="userDataList">
    <row>
       <cancelFlwNo>商户充值退回流水号</cancelFlwNo><!--商户充值退回流水号varchar(20) -->
         <status>liststatus</status><!--交易银行受理状态char(7)-->
         <statusText>liststatusText</statusText><!--交易银行受理状态信息 varchar(254)-->
  	</row>
  </list>
</stream>

 

 

这里面在整理的时候, 不是很方便整理. 而且还去掉了银行的缩写. 如有需要. 到时候再看有心情整理否.

 

 

------------------------------------------------------追加-----------------------

 

追加一点如果是 XML中的字段含有属性, 想获取属性值.原理差不多. 只是调用的方法不一样.

 

 

<?xml version="1.0" encoding="GB2312"?>
<items version="2.00" >
  <result name="status" value="0'/>
</items>
 

想要获取name 或者是 value的值.

 

 

digester.addSetProperties("items/result", "value", "resultStatus");
 

 在ruleset 里面 用这个就好了.   其中 resultStatus 是接受bean里面的一个属性.

 

 

 

--------------------------------------------------------继续追加----------------------------------------

 

如果是是下面这种格式的XML

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web>
<root name = "root_name1">
<bar id="0" title="The Zero Child"/>
<bar id="123" title="The First Child"/>
<bar id="456" title="The Second Child"/>
</root>
<root name = "root_name2">
<bar id="789" title="Another Child"/>
</root>
</web>

 

则可以用更简单的编码格式.

 

RuleSetBase

 

 

public class ConfigRuleSet extends RuleSetBase{        //注意,需要继承RuleSetBase
public void addRuleInstances(Digester digester){
digester.setValidating( false );
digester.addObjectCreate("web", WebConfig.class) ;
digester.addSetProperties("web");

digester.addObjectCreate( "web/root", Root.class );
digester.addSetProperties("web/root");
digester.addSetNext( "web/root", "addRoot" );

digester.addObjectCreate( "web/root/bar", Bar.class );
digester.addSetProperties("web/root/bar");
digester.addSetNext( "web/root/bar", "addBar" );

} 
}
 

编译解析XML

 

 

		final String fileName = "/card/bean/Item.xml" ;
		Items items = new Items() ;
		Digester digester = new Digester() ;
		ConfigRuleSet rule = new ConfigRuleSet();
		rule.addRuleInstances(digester) ;
		try {
			items = (Items)digester.parse(new File(fileName)) ;
		System.out.println("items size :" + items.getSize()) ;
		System.out.println("items getResult :"+items.getResult());
		Item[] item = items.getItemMap() ;
		for (int i = 0; i < item.length; i++) {
			System.out.println("item type:" + item[i].getType()) ;
			Param[] param = item[i].getParams() ;
			for (int j = 0; j < param.length; j++) {
				if(j>0) System.out.println("/t------------------");
					System.out.println("/param name:" + param[j].getName()) ;
					System.out.println("/param value:" + param[j].getValue()) ;
			}
		}
		} catch (IOException e) {
		e.printStackTrace();
		} catch (SAXException e) {
		e.printStackTrace();
		} 
 

然后是各个 bean 之间的关系, 这里就不整理了.

 

这里摘自 :http://blog.csdn.net/gooing/article/details/381399  

 

 

分享到:
评论

相关推荐

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

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

    利用commons-digester解析xml

    标题“利用commons-digester解析XML”涉及到的是Java开发中的一种处理XML文档的工具——Apache Commons Digester。这个库提供了一种方便的方式来映射XML文档结构到Java对象,从而简化了XML数据的处理过程。 Apache ...

    commons-digester.jar

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

    commons-digester-2.1.jar

    `commons-digester-2.1.jar` 是Apache Commons项目中的一个组件,主要负责XML文档的解析和对象的创建与绑定。Apache Commons Digester库提供了一种规则驱动的方法来解析XML文档,并根据预定义的规则将XML数据映射到...

    org.apache.commons 系列源文件

    在给定的压缩包文件中,我们看到了一系列与 org.apache.commons 相关的源代码,这些组件是 Java 开发中常用的工具类库。以下是关于这些组件的详细知识点: 1. **Commons Collections** (commons-collections-3.2.1-...

    使用Apache的Digester来解析XML文档

    Apache Digester是一个强大的Java库,专门用于将XML文档解析成对象模型。在处理XML到Java对象映射时,它提供了一种简洁的方式,避免了手动编写大量繁琐的XML解析代码。这个工具尤其适用于那些需要频繁从XML配置文件...

    使用digester解析XML

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

    xml解析commons-digester的demo

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

    Digester解析XML

    要使用Digester解析XML文档,首先需要创建一个 `org.apache.commons.digester.Digester` 类的实例,并配置必要的模式和规则,最后调用 `parse()` 方法。 以下是一个简单的示例代码: ```java import org.apache....

    使用Apache_Commons_Digester

    Apache Commons Digester 是一款基于 Java 的开源库,专门用于简化 XML 文件解析的过程。它利用 SAX(Simple API for XML)解析器来解析 XML 数据,并通过一系列预定义规则来创建 Java 对象模型。这种方式极大地简化...

    digester解析xml的问题.pdf

    Digester 是 Apache Commons 中的一个工具类库,它用于解析 XML 文档,并根据预先定义的规则自动创建和配置 Java 对象。在上述问题中,我们看到一个 XML 文档表示了一个考试,其中包含了多个题目,每个题目有其编号...

    digester解析xml必备包.rar

    3. **解析XML**:使用`parse`方法,传入XML文件的输入流,开始解析过程。 4. **处理结果**:解析完成后,根对象(通常是XML文档的顶级元素对应的Java对象)会被返回,其他对象可以通过根对象访问。 通过以上步骤,...

    使用Digester解析XML文档示例

    4. **解析XML文件**:使用Digester解析XML文件,并根据定义的规则创建Java对象。 #### 五、总结 通过上述介绍可以看出,Digester是一个非常有用的工具,它可以大大简化XML解析的过程。在实际开发中,尤其是处理...

    Apache xml转换java对象 Digester

    `Apache Commons Digester`是一个功能强大且易于使用的Java库,专门用于将XML文档解析并转换为Java对象。它支持通过规则集(Rules)来进行配置,这些规则集可以在代码中动态定义,也可以从XML文件中加载。这种方式...

    commons-digester-2.1.jar.zip

    import org.xml.sax.InputSource; public class DigesterExample { public static void main(String[] args) throws Exception { // 创建Digester实例 Digester digester = new Digester(); // 注册规则 ...

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

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

    Digester解析XML问题.pdf

    Apache Commons Digester是一个用于将XML数据映射到Java对象的工具,主要应用于处理XML配置文件或数据文件。它通过定义一系列的模式和规则,能够自动地创建和填充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"是一个...

Global site tag (gtag.js) - Google Analytics