0

I am using xmlunit 2.5.0.

Below are my two xml string : One is the controlxml and one is 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>";

Here i am comparing these two string xmls using xmlunit.

My java code is:

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();

Getting error:

***********************
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)
***********************

I want to get no error since Rose is present in the testxml. Why is Rose in controlxml is being compared to Daisy in testxml even though i have rose in the testxml and i have ElementSelectors.byName and whenElementIsNamed("f1").

Which ElementSelector should I use?

allcaps
  • 10,945
  • 1
  • 33
  • 54
DonSenor
  • 3
  • 2

1 Answers1

0

Your

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

means your "f1" elements will be in compared in document order. They all have the same name after all. You obviously feel the value of the name attribute is what identifies the "f1"s to compare. If the "f1" would be siblings then a simple

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

should work. byNameAndAttributes takes a varargs list of attributes whose values must match in addition to the element name.

Unfortunately they are not siblings and you must tell XMLUnit which "flower" elements to pick when traversing the tree. When XMLUnit picks up the wrong "flower"s, it is never going to see the "f1" you consider the same.

The full solution for your example is

.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
    .whenElementIsNamed("flower")
    .thenUse(ElementSelectors.byXPath("./f1", ElementSelectors.byNameAndAttributes("name")))
    .elseUse(ElementSelectors.byNameAndText)
    .build()))
Stefan Bodewig
  • 3,260
  • 15
  • 22
  • Hello sir, thank you for reply. i have changed it to org.xmlunit.diff.Diff myDiff = DiffBuilder.compare(controlXml).withTest(testXml) .checkForSimilar() // a different order is always 'similar' not equals. .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder() .whenElementIsNamed("f1") .thenUse(ElementSelectors.byNameAndAttributes("name")) .elseUse(ElementSelectors.byName) .build())) .build(); but getting error: – DonSenor Nov 01 '17 at 15:59
  • *********************** Expected child 'f1' but was 'null' - comparing at /flowers[1]/flower[1]/f1[1] to (DIFFERENT) *********************** *********************** Expected child 'null' but was 'f1' - comparing to at /flowers[1]/flower[1]/f1[1] (DIFFERENT) *********************** *********************** Expected child 'f1' but was 'null' - comparing at /flowers[1]/flower[2]/f1[1] to (DIFFERENT) *********************** Expected child 'null' but was 'f1' - comparing to at /flowers[1]/flower[2]/f1[1] (DIFFERENT) – DonSenor Nov 01 '17 at 16:03
  • I see the problem, your "f1" elements are nested into yet another element (I thought they would be siblings. I'll experiment and update the answer. – Stefan Bodewig Nov 01 '17 at 16:33