代码之家  ›  专栏  ›  技术社区  ›  Paul Morie

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

  •  29
  • Paul Morie  · 技术社区  · 15 年前

    我有一个这样的XML消息:

    <root>
      <elementA>something</elementA>
      <elementB>something else</elementB>
      <elementC>yet another thing</elementC>
    </root>
    

    我想将测试中的方法生成的这种类型的消息与预期的消息进行比较,但我不在乎 elementA . 因此,我希望上面的信息被认为等同于:

    <root>
      <elementA>something different</elementA>
      <elementB>something else</elementB>
      <elementC>yet another thing</elementC>
    </root>
    

    我使用的是最新版本的 XMLUnit .

    我在想象,答案包括创建一个自定义 DifferenceListener 如果有什么东西可以用的话,我只是不想重新发明轮子。

    欢迎使用xmlunit以外的库的建议。

    5 回复  |  直到 6 年前
        1
  •  14
  •   Jean-François Savard    8 年前

    事情改变了很多 XMLUnit 因为这个问题被回答了。

    当使用 DiffBuilder :

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

    如果你再打电话 documentDiff.hasDifferences() 添加到筛选器的节点将被忽略。

        2
  •  38
  •   Paul Morie    15 年前

    我最终实现了 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) {
    
        }
    }
    
        3
  •  8
  •   Community Ian Goodfellow    7 年前

    我将使用XSLT和 identity transform 过滤掉我想忽略的元素,并比较结果。

    XSL: how to copy a tree, but removing some nodes ? 早些时候就这样。

        4
  •  0
  •   Zheng Wang    6 年前

    现在你可以试试 ${xmlunit.ignore} 在xmlUnit 2.6.0中(添加依赖项xmlUnit占位符)。示例代码如下。

    Diff diff = DiffBuilder
        .compare(expectedXML)
        .withTest(actualXML)
        .withDifferenceEvaluator(new PlaceholderDifferenceEvaluator())
        .build();
    

    期望XML:

    <root>
      <elementA>${xmlunit.ignore}</elementA>
      <elementB>something else</elementB>
      <elementC>yet another thing</elementC>
    </root>
    

    实际XML:

    <root>
      <elementA>anything</elementA>
      <elementB>something else</elementB>
      <elementC>yet another thing</elementC>
    </root>
    

    请注意,当前的$xmlUnit.ignore只支持文本节点和属性值忽略,如 unit tests .

        5
  •  -1
  •   Vishal Chhodwani    6 年前
    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) {
    
        }
    }
    

    如何调用这个自己的实现到我的方法中,以查看特定节点被忽略后的差异进行比较。