ashes
ashes

Reputation: 13

XML comparison using XMLunit not working when elements are reordered

I have two XMLs

<books><book language="English"><authors><author>Niklaus Wirth</author></authors></book><book language="English"><authors><author>Mark Twain</author></authors></book><book language="English"><authors><author>O.-J. Dahl</author></authors></book></books>


<books><book language="English"><authors><author>Niklaus Wirth</author></authors></book><book language="English"><authors><author>O.-J. Dahl</author></authors></book><book language="English"><authors><author>Mark Twain</author></authors></book></books>

The order of the last two <author> tags are different and they should be similar. This is the code

public static void compare() throws FileNotFoundException{
        String sourceXML=convertXMLtoString(source);
        String targetXML=convertXMLtoString(target);
        System.out.println(sourceXML);
        System.out.println(targetXML);
        Diff mydiff=DiffBuilder.compare(sourceXML)
        .withTest(targetXML)
        .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))
        .checkForSimilar()
        //.withNodeMatcher()
        .build();
        Iterable<Difference> differences = mydiff.getDifferences();
        for(Difference d:differences){
            System.out.println(d.toString());
        }
    }

This is the ouput.

Expected child 'author' but was 'null' - comparing <author...> at /books[1]/book[2]/authors[1]/author[1] to <NULL> (DIFFERENT)
Expected child 'null' but was 'author' - comparing <NULL> to <author...> at /books[1]/book[2]/authors[1]/author[1] (DIFFERENT)
Expected child 'author' but was 'null' - comparing <author...> at /books[1]/book[3]/authors[1]/author[1] to <NULL> (DIFFERENT)
Expected child 'null' but was 'author' - comparing <NULL> to <author...> at /books[1]/book[3]/authors[1]/author[1] (DIFFERENT)

Can anyone please tell me how to ignore this?I thought using NameandText with Element selector should ignore the order. Thanks

Upvotes: 1

Views: 556

Answers (1)

user4524982
user4524982

Reputation:

Using byNameAndText you make sure you pick the correct author tags, but this is far too late as XMLUnit needs to select the correct book for your comparison to succeed. Once it has settled on which book element to compare it is never going to search for elements in a different subtree.

I don't think author is what distinguishes the books in the end, but in absence of any other hints something like

ElementSelectors.conditionalBuilder()
    .whenElementIsNamed("book").thenUse(ElementSelectors.byXPath("./authors/author", ElementSelectors.byNameAndText))
    .elseUse(ElementSelectors.byNameAndText)
    .build();

should probably work.

Upvotes: 1

Related Questions