1

I am writing a comparison util which lets me compare similarity of two xmls without considering the order. Am using xmlunit 2.4.0

org.xmlunit.diff.Diff diff = DiffBuilder.compare(xml1)
                .withTest(xml2)
                .checkForSimilar()
                .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))
                .build();

So with this, the below two xmls gets compared successfully

xml1:

<multistatus>
    <flowers>
        <flower>Roses</flower>
        <flower>Daisy</flower>
    </flowers>
    <flowers>
        <flower>Roses</flower>
        <flower>Daisy</flower>
    </flowers>
</multistatus>

xml2:

<multistatus>
    <flowers>
        <flower>Roses</flower>
        <flower>Daisy</flower>
    </flowers>
    <flowers>
        <flower>Daisy</flower>
        <flower>Roses</flower>
    </flowers>
</multistatus>

However this fails when i give the below input: xml1:

<multistatus>
    <flowers>
        <flower>Roses</flower>
    </flowers>
    <flowers>
        <flower>Daisy</flower>
    </flowers>
</multistatus>

xml2:

<multistatus>
    <flowers>
        <flower>Daisy</flower>
    </flowers>
    <flowers>
        <flower>Roses</flower>
    </flowers>
</multistatus>

I tried creating ElementSelector and even that is not helping.

ElementSelector selector = ElementSelectors.conditionalBuilder()
                .whenElementIsNamed("flowers").thenUse(ElementSelectors.byXPath("./flowers/flower", ElementSelectors.byNameAndText))
                .elseUse(ElementSelectors.byName)
                .build();

        org.xmlunit.diff.Diff diff = DiffBuilder.compare(refSource)
                .withTest(testSource)
                .checkForSimilar()
                .ignoreWhitespace()
                .normalizeWhitespace()
                .withNodeMatcher(
                        new DefaultNodeMatcher(
                                selector,ElementSelectors.Default)
                )
                .build();
paulophoenix
  • 89
  • 1
  • 10

1 Answers1

1

Your XPath doesn't match anything.

The context "." is the node you've selected with whenElementIsNamed so it is the respective "flowers" element.

You probably mean "./flower" - and it doesn't find any differences in your example.

Stefan Bodewig
  • 3,260
  • 15
  • 22
  • Yeah That fixed my second example but now it breaks for my first one. – paulophoenix Jan 12 '18 at 19:43
  • Your initial attempt at the first example only worked by accident. There is no built-in `ElementSelector` that is going to work for both of your examples as in order to figure out which "flowers" to pick you first need to establish whether the nested "flower" elements match. You probably need to write a more specific matcher yourself. – Stefan Bodewig Jan 14 '18 at 05:02
  • @ Stefan Bodewig. Is it possible with xmlUnit to have an approach which can work for first example? even with the customized node matcher. If yes, can you provide some pointers/guide through which this can be achieved. – hiren Aug 30 '19 at 06:07
  • Are you asking for a single configuration that would work for the first pair of XMLs (with two `flower` elements in each) as well as the second pair (with only one `flower` each but swapped `flowers`)? I'm sure that is not exactly the problem you are facing but a slightly different one and any concrete example would not work for you. – Stefan Bodewig Aug 30 '19 at 14:59
  • The general line of thought is: Consider you have a list of `Element`s that correspond to your `flowers` nodes. How do you know which ones to match. Translate this "how" to Java using DOM and wrap it in an `ElementSelector`. A more concrete answer doesn't fit inside a comment here :-) – Stefan Bodewig Aug 30 '19 at 14:59