web-dev-qa-db-ja.com

XMLを比較するときに特定の要素を無視するにはどうすればよいですか?

私は次のような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以外のライブラリを使用する提案を歓迎します。

29
Paul Morie

この質問に答えてから、 XMLUnit の状況は大きく変わりました。

DiffBuilderを使用するときに、ノードを簡単に無視できるようになりました。

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

その後、documentDiff.hasDifferences()を呼び出すと、フィルターに追加されたノードは無視されます。

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) {

    }
}
38
Paul Morie

XSLTと identity transform を使用して、無視したい要素を除外し、結果を比較します。

XSL:ツリーをコピーする方法、ただし一部のノードを削除する方法は? SOの前半を参照してください。

8
lavinio

XMLUnit2.6.0で${xmlunit.ignore}を試すことができるようになりました(依存関係xmlunit-placeholdersを追加します)。サンプルコードは以下の通りです。

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}はテキストノードと属性値の無知のみをサポートしていることに注意してください。

0
Zheng Wang