将XML与xmlunit进行比较时忽略文本差异

时间:2015-02-26 08:52:43

标签: java xml junit xmlunit

我在比较xml字符串时遇到了问题。

我的比较功能是

public static boolean compareXMLs(String xmlSource, String xmlCompareWith){

XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreComments(true);
XMLUnit.setIgnoreAttributeOrder(true);

XMLUnit.setNormalizeWhitespace(true);
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);

Diff myDiff = new Diff(xmlSource, xmlCompareWith);
myDiff.overrideDifferenceListener(new IgnoreTextAndAttributeValuesDifferenceListener());
return myDiff.similar();
}

我的单元测试是

 String xml1 = "<a>f</a>";
 String xml2 = "<a>1</a>";
 assertEquals(true, RestCommonUtility.compareXMLs(xml1, xml2));

 xml1 = "<a></a>";
 xml2 = "<a>1</a>";
 assertEquals(true, RestCommonUtility.compareXMLs(xml1, xml2));

我的单元测试在第一个断言中传递,但在第二个断言中失败。我设置IgnoreTextAndAttributeValuesDifferenceListener,但我的第二个断言仍然失败。有没有办法解决这个问题。或者是否有任何其他框架可以帮助进行这种比较?

2 个答案:

答案 0 :(得分:1)

您可以创建自己的DifferenceListener,当一个节点具有单个文本子节点而另一个节点没有时,忽略差异。这是一个例子:

public class CompareStructureOnlyListener implements DifferenceListener {

  private IgnoreTextAndAttributeValuesDifferenceListener delegate =
      new IgnoreTextAndAttributeValuesDifferenceListener();

  @Override
  public int differenceFound(Difference difference) {
    int delegateResult = delegate.differenceFound(difference);

    if (delegateResult == DifferenceListener.RETURN_ACCEPT_DIFFERENCE) {
      // Delegate thinks there is a difference, let's confirm

      if (difference.getId() == DifferenceConstants.HAS_CHILD_NODES_ID) {
        Node controlNode = difference.getControlNodeDetail().getNode();
        Node testNode = difference.getTestNodeDetail().getNode();

        Node nodeToTest = (controlNode.hasChildNodes()) ? controlNode : testNode;

        // If there is only a difference of one node and that node is a text
        // node, then ignore it
        if (nodeToTest.getChildNodes().getLength() == 1
            && nodeToTest.getFirstChild() instanceof Text) {
          return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR;
        } else {
          return DifferenceListener.RETURN_ACCEPT_DIFFERENCE;
        }
      }
    }  
    return delegateResult;
  }

  @Override
  public void skippedComparison(Node control, Node test) {
    // Does nothing
  }
}

以下是一些通过的测试:

String xml1 = "<a>a</a>";
String xml2 = "<a>1</a>";
assertTrue(compareXMLs(xml1, xml2));

xml1 = "<a></a>";
xml2 = "<a>1</a>";
assertTrue(compareXMLs(xml1, xml2));

xml1 = "<a></a>";
xml2 = "<a><f></f></a>";
assertFalse(compareXMLs(xml1, xml2));

附注:将compareXMLs方法重命名为xmlsAreSimilar,或者轻松指示布尔返回值的含义。

答案 1 :(得分:0)

如果报告的错误是CH​​ILD_NODELIST_LENGTH,则创建一个自定义IgnoreTextAndAttributeValuesDifferenceListener,它也会忽略CHILD_NODELIST_LENGTH。我通过调试器运行它来确认区别是什么然后将其排除