比较XML时如何忽略某些元素?

Pau*_*rie 30 java xml junit xmlunit

我有这样的XML消息:

<root>
  <elementA>something</elementA>
  <elementB>something else</elementB>
  <elementC>yet another thing</elementC>
</root>
Run Code Online (Sandbox Code Playgroud)

我想比较一个由测试方法产生的这种类型的消息与预期的消息,但我不在乎elementA.所以,我希望上述消息被认为是等于:

<root>
  <elementA>something different</elementA>
  <elementB>something else</elementB>
  <elementC>yet another thing</elementC>
</root>
Run Code Online (Sandbox Code Playgroud)

我正在使用最新版本的XMLUnit.

我想象的答案涉及创造一个习俗DifferenceListener; 如果那里有可以使用的东西,我只是不想重新发明轮子.

建议使用XMLUnit以外的库.

Pau*_*rie 38

我最终实现了一个带有DifferenceListener一个节点名称列表(带有名称空间)来忽略文本差异:

public class IgnoreNamedElementsDifferenceListener implements DifferenceListener {
    private Set<String> blackList = new HashSet<String>();

    public IgnoreNamedElementsDifferenceListener(String ... elementNames) {
        for (String name : elementNames) {
            blackList.add(name);
        }
    }

    public int differenceFound(Difference difference) {
        if (difference.getId() == DifferenceConstants.TEXT_VALUE_ID) {
            if (blackList.contains(difference.getControlNodeDetail().getNode().getParentNode().getNodeName())) {
                return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            }
        }

        return DifferenceListener.RETURN_ACCEPT_DIFFERENCE;
    }

    public void skippedComparison(Node node, Node node1) {

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我很惊讶这是复杂的 - 如果xmlunit没有内置的东西来忽略特定的元素,我会感到很失望吗? (14认同)

Jea*_*ard 15

自从回答这个问题以来,XMLUnit已经发生了很多变化.

现在,您可以在使用时轻松忽略节​​点DiffBuilder:

final Diff documentDiff = DiffBuilder
            .compare(expectedSource)
            .withTest(actualSource)
            .withNodeFilter(node -> !node.getNodeName().equals(someName))
            .build();
Run Code Online (Sandbox Code Playgroud)

如果您随后调用documentDiff.hasDifferences()添加到过滤器的节点将被忽略.


lav*_*nio 8

我会使用XSLT和身份转换来过滤掉我想忽略的元素,并比较结果.

请参阅XSL:如何复制树,但删除一些节点?早在SO上.


Zhe*_*ang 6

您现在可以在 XMLUnit 2.6.0 中尝试${xmlunit.ignore}(添加依赖项 xmlunit-placeholders)。示例代码如下。

Diff diff = DiffBuilder
    .compare(expectedXML)
    .withTest(actualXML)
    .withDifferenceEvaluator(new PlaceholderDifferenceEvaluator())
    .build();
Run Code Online (Sandbox Code Playgroud)

预期的 XML:

<root>
  <elementA>${xmlunit.ignore}</elementA>
  <elementB>something else</elementB>
  <elementC>yet another thing</elementC>
</root>
Run Code Online (Sandbox Code Playgroud)

实际的 XML:

<root>
  <elementA>anything</elementA>
  <elementB>something else</elementB>
  <elementC>yet another thing</elementC>
</root>
Run Code Online (Sandbox Code Playgroud)

请注意,当前 ${xmlunit.ignore} 仅支持文本节点和属性值忽略,从单元测试中可以看出。