您的位置:首页 > 其它

XML字符串对比技巧二

2009-03-10 10:24 316 查看
之前都使用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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: