Тег XMLUnit, содержащий атрибут name не совпадает

Я использую xmlunit 2.5.0.

Ниже приведены мои две строки XML: controlxml и один testxml,

String controlXml = "<flowers><flower><f1 name = \"Roses\"/></flower><flower><f1 name = \"Daisy\"/></flower><flower><f1 name = \"Crocus\"/></flower></flowers>";

String testXml = "<flowers><flower><f1 name = \"Daisy\"/></flower><flower><f1 name = \"Roses\"/></flower><flower><f1 name = \"Crocus\"/></flower></flowers>";

Здесь я сравниваю эти две строки xmls, используя xmlunit.

Мой код Java:

org.xmlunit.diff.Diff myDiff = DiffBuilder.compare(controlXml).withTest(testXml)
                    .checkForSimilar() 
                    .withNodeMatcher(new 
                     DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
                               .whenElementIsNamed("f1")
                               .thenUse(ElementSelectors.byName)
                               .elseUse(ElementSelectors.byNameAndText)
                               .build()))
                    .build();

Получение ошибки:

***********************
Expected attribute value 'Roses' but was 'Daisy' - comparing <f1 name="Roses"...> at /flowers[1]/flower[1]/f1[1]/@name to <f1 name="Daisy"...> at /flowers[1]/flower[1]/f1[1]/@name (DIFFERENT)
***********************
***********************
Expected attribute value 'Daisy' but was 'Roses' - comparing <f1 name="Daisy"...> at /flowers[1]/flower[2]/f1[1]/@name to <f1 name="Roses"...> at /flowers[1]/flower[2]/f1[1]/@name (DIFFERENT)
***********************

Я не хочу получить ошибку, так как Роза присутствует в testxml. Почему Rose в controlxml сравнивается с Daisy в testxml, хотя я поднялся в testxml и у меня есть ElementSelectors.byName а также whenElementIsNamed("f1"),

Какой ElementSelector я должен использовать?

1 ответ

Решение

Ваш

.whenElementIsNamed("f1")
.thenUse(ElementSelectors.byName)

означает, что ваши элементы "f1" будут сравниваться в порядке документа. Они все имеют одно и то же имя. Вы, очевидно, чувствуете ценность name Атрибут - это то, что идентифицирует "f1" для сравнения. Если "f1" будет братьями и сестрами, то простое

.thenUse(ElementSelectors.byNameAndAttributes("name"))

должно сработать. byNameAndAttributes принимает список атрибутов varargs, значения которых должны совпадать в дополнение к имени элемента.

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

Полное решение для вашего примера

.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
    .whenElementIsNamed("flower")
    .thenUse(ElementSelectors.byXPath("./f1", ElementSelectors.byNameAndAttributes("name")))
    .elseUse(ElementSelectors.byNameAndText)
    .build()))
Другие вопросы по тегам