使用XMLUnit比较动态变化的XML

时间:2018-04-18 07:00:09

标签: java xml xmlunit

目前我正在使用XMLunit进行测试。我有两个XML如下。 XML1

<envelope>
<NameValuePairs>
<Name>Karthick</Name>
<value>yes</value>
</NameValuePairs>
<NameValuePairs>
<Name>Anu</Name>
<value>yes</value>
</NameValuePairs>
<NameValuePairs>
<Name>Annie</Name>
<value>No</value>
</NameValuePairs>
<NameValuePairs>
<Name>Aishu</Name>
<value>No</value>
</NameValuePairs>
</envelope>

XML2

<envelope>
    <NameValuePairs>
        <Name>Annie</Name>
        <value>yes</value>
    </NameValuePairs>
    <NameValuePairs>
        <Name>Aishu</Name>
        <value>yes</value>
    </NameValuePairs>
    <NameValuePairs>
        <Name>Karthick</Name>
        <value>No</value>
    </NameValuePairs>
    <NameValuePairs>
        <Name>Anu</Name>
        <value>No</value>
    </NameValuePairs>
</envelope>

问题1: 如上例所示,节点“nameValuePair”每次都会动态变化。 XMLUnit认为这是差异。
问题2:
即使节点“name”发生更改且“value”为yes或no,XMLUnit也不会将其识别为差异。

请建议我比较这种XML的方法。

1 个答案:

答案 0 :(得分:0)

从您的描述中我理解您认为那些具有NameValuePairs子元素且具有相同嵌套文本的Name元素相同。并且您希望XMLUnit忽略NameValuePairs实例的顺序,只要它按上面的定义选择“正确”对。这是对的吗?

如果是这样,你需要告诉XMLUnit哪些NameValuePairs是彼此要比较的,这是ElementSelector的工作(假设这里是XMLUnit 2.x)。您的示例与XMLUnit's User Guide中的tr示例相同,我建议您去那里了解详情。

每当XMLUnit遇到一组兄弟元素时,都会咨询ElementSelector以决定哪些分支相互比较。一旦选择了分支机构,就无法回头了。即当XMLUnit决定按文档顺序比较NameValuePairs元素时,它永远不会查看与当前所在分支不同的分支中的Name元素。这意味着您需要告诉XMLUnit选择哪个分支根据需要在文档层次结构中处于高位。

在你的情况下,你确实有一个envelope,所以ElementSelector只要它愿意比较那里的唯一元素就不重要了。 NameValuePairs的子项都具有不同的元素名称,因此ElementSelectors.byName将适用于它们 - 以及envelope

翻译我的第一句话“你认为NameValuePairs元素与具有相同嵌套文本的Name子元素相同”到XMLUnit的内置ElementSelector我最终ElementSelectors.byXPath("./Name", ElementSelectors.byNameAndText)(其中byName中的byNameAndText部分有些多余,因为XPath已确保名称相同)。将这些放在一起你需要使用ElementSelector

ElementSelectors.conditionalBuilder()
    .whenElementIsNamed("NameValuePair").thenUse(ElementSelectors.byXPath("./Name", ElementSelectors.byNameAndText))
    .elseUse(ElementSelectors.byName)
    .build();

因为XMLUnit应该与NameValuePairs匹配,即使它们不是有序的,并检测“匹配对”的Value元素是否有更改的嵌套文本。