XML字符串对比技巧二

之前都使用XmlUnit来对比xml字符串,今天发现当出现如下需求时,XMLUNIT无法满足或者说有bug,特自己写了对比方法。
需求:需要对比如下xml字符串,要求不对比其中的sign和time字段,其他字段都需要对比。
<?xml version="1.0" encoding="utf-8"?>
<SlotPermResult-array>
 <SlotPermResult>
  <appId>elbert_app_dsc007</appId>
  <slotIds>elb_wsi_001</slotIds>
  <time>1236586307734</time>
  <sign>822a379aec82755afaa9c63eea3b05b9</sign>
  <errorCode></errorCode>
  <errorMessage></errorMessage>
 </SlotPermResult>
 <SlotPermResult>
  <appId>elbert_apx_dsc008</appId>
  <slotIds></slotIds>
  <time>1236586307734</time>
  <sign>7ce9e326cb28b0084f7f331dcbb79f50</sign>
  <errorCode></errorCode>
  <errorMessage></errorMessage>
 </SlotPermResult>
 <SlotPermResult>
  <appId>elbert_app_dsc008</appId>
  <slotIds>elb_wsi_002</slotIds>
  <time>1236586307734</time>
  <sign>2ea135b978c75fb639fe65909283dcba</sign>
  <errorCode></errorCode>
  <errorMessage></errorMessage>
 </SlotPermResult>
</SlotPermResult-array>
尝试使用XmlUnit的方法
XMLAssert.assertXpathValuesEqual(path7,ExpXmlText,path7,ActXmlText);
结果发现只对第一个SlotPermResult节点的内容(子节点进行对比),不符合我们的需求。
原因XMLAssert根据Path找节点,只找第一个节点。所以只好自己写代码。
关键函数,需要根据Path找到符合这一路径的所有节点源码如下
 public static NodeList selectNodes(String express, String xmlStr) throws Exception
 {//查找节点,返回符合条件的节点集。
  DocumentBuilder builder = factory.newDocumentBuilder();
  InputStream is = String2InputStream(xmlStr);
  org.w3c.dom.Document doc = builder.parse(is);
  org.w3c.dom.Element root = doc.getDocumentElement();
  NodeList result = null;
  XPathFactory xpathFactory = XPathFactory.newInstance();
  XPath xpath = xpathFactory.newXPath();
  try {
   result = (NodeList) xpath.evaluate(express, root,
     XPathConstants.NODESET);
  } catch (XPathExpressionException e) {
   e.printStackTrace();
  }
  return result;
 }
辅助函数:由于我们要传入的都是XML字符串,所以在这之前需要把字符串转成Stream
源码如下
 static InputStream String2InputStream(String str) throws Exception{
     ByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes("utf-8"));
     return stream;
 }
搞定之后,我们需要对所有需要对比的路径都放在List参数中传给对比函数,让对比函数逐一进行对比
对比函数源码如下
 @SuppressWarnings("unchecked")
 public static void assertEqualsNodes(String ExpXml,String ActXml,List list) throws Exception 
 {
  for(int i =0; i < list.size(); i++)
  {
   String path = list.get(i).toString();
   NodeList nlExp = XmlStringUtil.selectNodes(path, ExpXml);
   NodeList nlAct = XmlStringUtil.selectNodes(path, ActXml);
   Assert.assertEquals(path+"路径下的节点数目不相同:",nlExp.getLength(),nlAct.getLength());
   for(int j=0 ; j< nlExp.getLength(); j++)
   {
    Assert.assertEquals(path+"路径下第"+j+"个节点内容:",nlExp.item(j).getTextContent(),nlAct.item(j).getTextContent());
   }
   
   //Assert.assertEquals(nlExp,nlAct);
  }
 }
调用时候的代码片段如下:
 String ExpXmlText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    + "<SlotPermResult-array>  " + "<SlotPermResult>    "
    + "<appId>elbert_app_dsc007</appId>    "
    + "<slotIds>elb_wsi_001</slotIds>    "
    + "<time>1236586307734</time>    "
    + "<sign>822a379aec82755afaa9c63eea3b05b9</sign>    "
    + "<errorCode></errorCode>    "
    + "<errorMessage></errorMessage>  " + "</SlotPermResult>  "
    + "<SlotPermResult>    "
    + "<appId>elbert_apx_dsc008</appId>    "
    + "<slotIds></slotIds>    " + "<time>1236586307734</time>    "
    + "<sign>7ce9e326cb28b0084f7f331dcbb79f50</sign>    "
    + "<errorCode></errorCode>    "
    + "<errorMessage></errorMessage>  " + "</SlotPermResult>  "
    + "<SlotPermResult>    "
    + "<appId>elbert_app_dsc008</appId>    "
    + "<slotIds>elb_wsi_002</slotIds>    "
    + "<time>1236586307734</time>    "
    + "<sign>2ea135b978c75fb639fe65909283dcba</sign>    "
    + "<errorCode></errorCode>    "
    + "<errorMessage></errorMessage>  "
    + "</SlotPermResult></SlotPermResult-array>";
  List<String> Nodes = new ArrayList<String>();
  Nodes.add("/SlotPermResult-array/SlotPermResult/appId");
  Nodes.add("/SlotPermResult-array/SlotPermResult/slotIds");
  Nodes.add("/SlotPermResult-array/SlotPermResult/errorCode");
  Nodes.add("/SlotPermResult-array/SlotPermResult/errorMessage");
。。。。(在这里通过测试执行得到ActXmlTest)
  assertEqualsNodes(ExpXmlText, ActXmlTest,Nodes);


本文转自elbertchen 51CTO博客,原文链接:http://blog.51cto.com/linkyou/282601,如需转载请自行联系原作者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值