XMLUnit比较Xml比较错误的节点

时间:2015-10-07 15:17:16

标签: xml compare xmlunit

当父节点的顺序不同时,我遇到了问题。 例如:

示例XML1

<level1>
   <name>FirstParent</name>
   <level2>
        <somefield>AAA</somefield>
   </level2>
   <level2>
        <somefield>BBB</somefield>
   </level2>       
</level1>
<level1>
   <name>SecondParent</name>
   <level2>
        <somefield>CCC</somefield>
   </level2>
   <level2>
        <somefield>DDD</somefield>
   </level2>
</level1>

示例XML2

<level1>
   <name>SecondParent</name>
   <level2>
        <somefield>DDD</somefield>
   </level2>
   <level2>
        <somefield>CCC</somefield>
   </level2>
</level1>
<level1>
   <name>FirstParent</name>
   <level2>
        <somefield>BBB</somefield>
   </level2>
   <level2>
        <somefield>AAA</somefield>
   </level2>          
</level1>

当我调试RecursiveElementNameAndTextQualifier时,我看到它将FirstParent作为controlnode,SecondParent作为testnode。因此,正确地断定节点是不同的。但我需要的是将FirstParent和SeconParent与其他文件中的正确匹配进行比较。

所以,似乎我需要先对更高级别的节点进行排序(?)。

有谁知道我怎么能克服这个?我应该以什么方式检查/修改/实现以将正确的父级串联传递给ElementQualifier?

也许,只要有正确的指示,我就可以开发出所需的东西。

4 个答案:

答案 0 :(得分:1)

您需要考虑获取文档相同分支所需的条件。根据您的描述,您希望将两个level1元素与其交换的订单进行比较。听起来好像你想通过查看嵌套在其中的第一个name子元素的文本内容来识别匹配对。就这篇文章而言,没有别的。

这不是RecursiveElementNameAndTextQualifier所做的。它比较了所有子元素的元素名称和嵌套文本。由于somefield元素的顺序是交换的,因此您想要比较的节点不符合条件。

您会看到XMLUnit按顺序选择level1元素,因为当完全没有找到匹配的节点对时,它会回退到这样做。如果您将compareUnmatched设置为false,则会产生CHILD_NODE_NOT_FOUND差异。

在XMLUnit 1.x(2.x还没有发布)中,你必须编写一个ElementQualifier来嵌入你自己需要的逻辑,没有内置的ElementQualifier完全符合您的要求。

答案 1 :(得分:1)

您尚未指定是使用XMLUnit 1还是2,但是在版本2(2.0.0-alpha-04)中使用DiffBuilder我遇到了这个问题。解决方案是构造Diff将非默认的ElementSelector传递给Default Matcher:

import org.xmlunit.diff.Diff;
import org.xmlunit.builder.DiffBuilder;
import org.xmlunit.diff.ElementSelectors;
import org.xmlunit.diff.DefaultNodeMatcher;

。 。

Diff diff = DiffBuilder.
            compare(myExpectedResultXmlObj).
            withTest(myCompareToXmlObj).
            withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)). 
            build();

Assert.assertFalse(diff.toString(), diff.hasDifferences());

关键部分是withNodeMatcher行。

答案 2 :(得分:0)

您需要提供自己的ElementQualifier实施方案。 RecursiveElementNameAndTextQualifier可能会将一个文档中的相同元素与另一个文档中的多个元素进行匹配。

答案 3 :(得分:0)

对我来说,我还需要在checkForSimilar()上添加方法DiffBuilder

没有它,断言是错误的,说节点的顺序不一样(子列表中的位置不一样)

我的代码是:

Diff diff = DiffBuilder
    .compare(myExpectedResultXmlObj)
    .withTest(myCompareToXmlObj)
    .checkForSimilar()
    .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName))
    .build();