Как сопоставить/игнорировать определенный тег при сравнении XML?

Я сравниваю 2 XML, используя XMLUnit 2.xx, оба имеют одинаковую структуру, за исключением имени корневого узла:

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

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

Я ищу способ сказать diffBuilder, что expectedValue == value или просто проигнорировать это конкретное сравнение.

Есть идеи ? Спасибо


person user3718160    schedule 06.03.2018    source источник


Ответы (2)


Я нашел способ игнорировать конкретное сравнение двух конкретных имен тегов.

Я дам свой ответ здесь, если это кому-то когда-нибудь понадобится

Сначала создайте собственный DifferenceEvaluator:

public class IgnoreTagNameDifferenceEvaluator implements DifferenceEvaluator {

    Map<String,String> map;

    public IgnoreTagNameDifferenceEvaluator(Map<String,String> map){
        this.map = map;
    }

    @Override
    public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) {
        if (outcome == ComparisonResult.EQUAL) return outcome; // only evaluate differences.

        if(comparison.getType() == ComparisonType.ELEMENT_TAG_NAME){
            String value = map.get(comparison.getControlDetails().getValue());
            if(value != null && value.equals(comparison.getTestDetails().getValue())){
                return ComparisonResult.SIMILAR;
            }
        }
        return outcome;
    }
}

Затем свяжите его с diffBuilder следующим образом:

diffBuilder = diffBuilder.withDifferenceEvaluator(DifferenceEvaluators.chain(
                DifferenceEvaluators.Default, new IgnoreTagNameDifferenceEvaluator(tagMap)));
person user3718160    schedule 07.03.2018

Это немного искажает идею равенства в XML :-)

Вам нужно сделать две вещи, во-первых, вам нужно предоставить свой собственный ElementSelector, который сообщает XMLUnit даже сравнивать узлы expectedValue и value. Во второй части вам нужен DifferenceEvaluator, который говорит, что разница в имени узла в порядке.

Что-то типа

public static void main(String[] args) {
    String x1 = "<expectedValue>"
        + "  <elementA>something</elementA>"
        + "  <elementB>something else</elementB>"
        + "  <elementC>yet another thing</elementC>"
        + "</expectedValue>";
    String x2 = "<value>"
        + "  <elementA>something</elementA>"
        + "  <elementB>something else</elementB>"
        + "  <elementC>yet another thing</elementC>"
        + "</value>";
    NodeMatcher m = new DefaultNodeMatcher(ElementSelectors.or((e1, e2) -> {
            if (e1 == null || e2 == null) {
                return false;
            }
            return "expectedValue".equals(e1.getLocalName())
                && "value".equals(e2.getLocalName());
        }), ElementSelectors.byName);
    Diff d = DiffBuilder.compare(x1)
        .withTest(x2)
        .withNodeMatcher(m)
        .withDifferenceEvaluator(DifferenceEvaluators
            .downgradeDifferencesToEqual(ComparisonType.ELEMENT_TAG_NAME))
        .build();
    System.err.println(d);
}

подойдет для простого случая.

person Stefan Bodewig    schedule 07.03.2018
comment
К сожалению, это не работает. Я сохраняю ту же ошибку. Ожидаемое имя тега элемента «expectedValue», но было «value». Но вдобавок ко всему я получаю сообщение об ошибке для всех дочерних элементов узла. - person user3718160; 07.03.2018
comment
это странно, поскольку я скопировал код из тестового примера, содержащего ваши XML-файлы, которые проходят. Я обновлю ответ, чтобы показать полный тест. - person Stefan Bodewig; 07.03.2018