【问题标题】:how to compare two different XML with all tags and show the difference?如何将两个不同的 XML 与所有标签进行比较并显示差异?
【发布时间】:2016-10-15 14:35:01
【问题描述】:

预期的 XML

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <bvoip:updateCustSiteDetailResponse xmlns:bvoip="http://dbor.att.com/bvoip/v1">
<bvoip:rowsAffected>13</bvoip:rowsAffected>
<bvoip:name>JAK</bvoip:name>
</bvoip:updateCustSiteDetailResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope><!-- P-V : 2016.10.21 -->

目标XML

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SOAP-ENV:Body>
<ns:updateCustSiteDetailResponse xmlns:ns="http://dbor.att.com/bvoip/v1">
      <ns:rowsAffected>14</ns:rowsAffected>
    </ns:updateCustSiteDetailResponse>  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

输出 ------------ 预期 rowsAffected 13 但 rowsAffected 为 14 缺少预期的名称

【问题讨论】:

  • 命名空间相同;为什么要忽略它?
  • 是的命名空间是不同的 bvoip 和 ns ,我只需要比较标签的值
  • 这是一个命名空间前缀;两个前缀的命名空间相同,http://dbor.att.com/bvoip/v1。鉴于命名空间是相同的;为什么要忽略它?
  • sry 忽略命名空间前缀和我的预期输出为 1) rowsAffected 13 但 rowsAffected 为 14 2) 名称丢失
  • 我在 xmlUnit 中做到了这一点,得到了不同的响应,如 [不同] 预期的子节点数为 '2' 但为 '1' - 比较 /Envelope[ 处的 1] 到 在 /Envelope[1]

标签: java xml web-services jakarta-ee xpath


【解决方案1】:

有两种选择

a) 使用类似 XMLUnit 的库,获取差异并忽略命名空间并比较文本值

b) 推出您自己的差异比较器。如果您只需要比较一个特定的标签(并且您不想要额外的依赖项或 JAXP),您可以使用这种方法。

public static void main(String[] args) throws XPathExpressionException {
        String controlXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">  <SOAP-ENV:Header/>  <SOAP-ENV:Body>    <bvoip:updateCustSiteDetailResponse xmlns:bvoip=\"http://dbor.att.com/bvoip/v1\"><bvoip:rowsAffected>13</bvoip:rowsAffected><bvoip:name>JAK</bvoip:name></bvoip:updateCustSiteDetailResponse>  </SOAP-ENV:Body></SOAP-ENV:Envelope>";
        String resultXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">  <SOAP-ENV:Body><ns:updateCustSiteDetailResponse xmlns:ns=\"http://dbor.att.com/bvoip/v1\">      <ns:rowsAffected>14</ns:rowsAffected>    </ns:updateCustSiteDetailResponse>  </SOAP-ENV:Body></SOAP-ENV:Envelope>";
        String xPath = "//*[local-name()='rowsAffected']";
        XPath xPathFactory = XPathFactory.newInstance().newXPath();
        Document controlDocument = getXMLDocument(controlXML);
        Document resultDocument = getXMLDocument(resultXML);
        Assert.assertEquals(xPathFactory.compile(xPath).evaluate(controlDocument),
                xPathFactory.compile(xPath).evaluate(resultDocument));

    }

    static private Document getXMLDocument(String xml) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        Document document = null;
        try {
            builder = factory.newDocumentBuilder();
            document = builder.parse(new InputSource(new StringReader(xml)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return document;
    }

上面的代码如预期的那样使断言失败并给了我结果

Exception in thread "main" junit.framework.ComparisonFailure: The text nodes do not match expected:<1[3]> but was:<1[4]>
    at junit.framework.Assert.assertEquals(Assert.java:81)
    at org.ram.so.SOProject.XMLCompare.main(XMLCompare.java:26)

【讨论】:

  • 但是标签在这里是动态的 String xPath = "//*[local-name()='rowsAffected']";
  • 在预期的响应中
  • 你的回答对我更有用,假设标签预期响应 155
  • targetXML as 14...它将是动态的,取决于请求..
猜你喜欢
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
相关资源
最近更新 更多