【问题标题】:XMLUnit Compare Xml comparing wrong NodesXMLUnit 比较 Xml 比较错误的节点
【发布时间】:2015-10-07 15:17:16
【问题描述】:

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

示例 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 ?

也许,有了正确的方向,我可以开发所需的东西。

【问题讨论】:

    标签: xml compare xmlunit


    【解决方案1】:

    您需要考虑提取文档的相同分支所需的条件。根据您的描述,您想将两个 level1 元素与其交换的顺序进行比较。听起来好像您想通过查看嵌套在其中的第一个 name 子元素的文本内容来识别匹配对。仅此文本,仅此而已。

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

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

    在 XMLUnit 1.x(2.x 尚未发布)中,您必须编写一个 ElementQualifier 来嵌入您自己需要的逻辑,没有内置的 ElementQualifier 完全可以做到你想要什么。

    【讨论】:

    • 嗨 Stefan,感谢您的回复。您确定这是我需要开发的 ElementQualifier 类吗?我不是一个 Java 人,但我可以试一试。您能否指出选择用于比较的节点是从什么、何时或何地开始的?这样,我可以在此之前放置代码对元素进行排序,然后只发送正确的几个节点来与现有函数进行比较。 TY
    • 这可能会变得更加复杂。请参阅DifferenceEngine 中的compareNodeList 方法。
    【解决方案2】:

    您尚未指定是使用 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 行。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 在 RecursiveElementNameAndTextQualifier 内我有 compareNodes 调用。该调用将 FirstParent 作为 currentControl 传递,将 SecondParent 作为 currentTest 传递。你知道打电话的时间/地点吗?
      • compareNodes()被qualifyForComparison()的接口方法调用,被Diff的compare()方法调用。
      【解决方案4】:

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

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

      我的代码是:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-21
        • 2018-09-28
        相关资源
        最近更新 更多