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);

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值