Search code examples
.netxmlunitxmldiff

How to ignore element order when diffing with XmlUnit


I have XML in the following format:

<Root>
    <Elem1>
        <SubElem1>A</SubElem1>
        ...
    </Elem1>
    <Elem1>
        <SubElem1>B</SubElem1>
        ...
    </Elem1>
    <Elem2>
        ...
    </Elem2>
    ...
</Root>

I want to instruct XmlUnit's diff engine to ignore the order of ElemN elements, but only within their "group".

E.g.:

  • If the second and the first Elem1 in the previous example would change order => equal
  • If the Elem2 would become before Elem1 or in the middle of Elem1 => difference

Is there a way to achieve this result?


Solution

  • Yes, this is the job of ElementSelector. By default XMLUnit (2.x) compares elements in the order they appear in but you can influence which of the siblings are picked by using an ElementSelector.

    I your case you seem to be happy with choosing elements in order unless they are named Elem1. For Elem1 you'd like to choose pairs based on the text nested into the SubElement1 child. One way to write such an ElementSelector could be

    ElementSelectors.ConditionalBuilder()
        .WhenElementIsNamed("Elem1")
        .ThenUse(ElementSelectors.ByXPath("./SubElem1", ElementSelectors.ByNameAndText))
        .ElseUse(ElementSelectors.Default)
        .Build();
    

    See the XMLUnit user guide for more details and examples.