Как игнорировать определенные элементы при сравнении XML? - PullRequest
29 голосов
/ 07 августа 2009

У меня есть 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 ]

38 голосов
/ 07 августа 2009

Я реализовал 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) {

    }
}
15 голосов
/ 25 мая 2016

С момента ответа на этот вопрос многое изменилось для XMLUnit .

Теперь вы можете легко игнорировать узел при использовании DiffBuilder:

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

Если вы затем вызовете documentDiff.hasDifferences() узлы, добавленные в фильтр, будут игнорироваться.

8 голосов
/ 07 августа 2009

Я бы использовал XSLT и преобразование идентичности , чтобы отфильтровать элементы, которые я хочу игнорировать, и сравнить результаты.

См. XSL: как скопировать дерево, но удаляя некоторые узлы? ранее на SO.

0 голосов
/ 26 июня 2018

Теперь вы можете попробовать ${xmlunit.ignore} в XMLUnit 2.6.0 (добавить зависимость xmlunit-placeholder). Пример кода приведен ниже.

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 голосов
/ 06 июня 2017
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) {

    }
}

Как вызвать эту собственную реализацию в моем методе, чтобы увидеть различия после того, как конкретный узел игнорируется для сравнения .?

...