0

I'm comparing 2 XML using XMLUnit 2.xx both of them have the same structure except for the root node name :

<expectedValue>
  <elementA>something</elementA>
  <elementB>something else</elementB>
  <elementC>yet another thing</elementC>
</expectedValue>

<value>
  <elementA>something</elementA>
  <elementB>something else</elementB>
  <elementC>yet another thing</elementC>
</value>

I'm searching for a way to say to the diffBuilder that expectedValue == value or eventually just ignore this specific comparison.

Any idea ? Thank you

user3718160
  • 481
  • 2
  • 11
  • 23

2 Answers2

0

This is bending the idea of equality in XML quite a bit :-)

You need to do two things, first you need to provide an ElementSelector of your own that tells XMLUnit to even compare the expectedValue and value nodes. In a second part you need a DifferenceEvaluator that says the difference in node name is fine.

Something like

public static void main(String[] args) {
    String x1 = "<expectedValue>"
        + "  <elementA>something</elementA>"
        + "  <elementB>something else</elementB>"
        + "  <elementC>yet another thing</elementC>"
        + "</expectedValue>";
    String x2 = "<value>"
        + "  <elementA>something</elementA>"
        + "  <elementB>something else</elementB>"
        + "  <elementC>yet another thing</elementC>"
        + "</value>";
    NodeMatcher m = new DefaultNodeMatcher(ElementSelectors.or((e1, e2) -> {
            if (e1 == null || e2 == null) {
                return false;
            }
            return "expectedValue".equals(e1.getLocalName())
                && "value".equals(e2.getLocalName());
        }), ElementSelectors.byName);
    Diff d = DiffBuilder.compare(x1)
        .withTest(x2)
        .withNodeMatcher(m)
        .withDifferenceEvaluator(DifferenceEvaluators
            .downgradeDifferencesToEqual(ComparisonType.ELEMENT_TAG_NAME))
        .build();
    System.err.println(d);
}

will do for the simple case.

Stefan Bodewig
  • 3,260
  • 15
  • 22
  • Saddly it doesn't work. I keep the same error Expected element tag name 'expectedValue' but was 'value' But on top of that I get an error on all the childs of the node Expected child '...' but was 'null' – user3718160 Mar 07 '18 at 07:15
  • this is strange, as I copied the code from a test case containing your XMLs that passes. I'll update the answer to show the full test. – Stefan Bodewig Mar 07 '18 at 11:02
0

I found a way to ignore the specific comparison of the 2 specific tag name.

I'll give my answer here if someone ever need it

First make a custom DifferenceEvaluator:

public class IgnoreTagNameDifferenceEvaluator implements DifferenceEvaluator {

    Map<String,String> map;

    public IgnoreTagNameDifferenceEvaluator(Map<String,String> map){
        this.map = map;
    }

    @Override
    public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) {
        if (outcome == ComparisonResult.EQUAL) return outcome; // only evaluate differences.

        if(comparison.getType() == ComparisonType.ELEMENT_TAG_NAME){
            String value = map.get(comparison.getControlDetails().getValue());
            if(value != null && value.equals(comparison.getTestDetails().getValue())){
                return ComparisonResult.SIMILAR;
            }
        }
        return outcome;
    }
}

Then link it to the diffBuilder like this :

diffBuilder = diffBuilder.withDifferenceEvaluator(DifferenceEvaluators.chain(
                DifferenceEvaluators.Default, new IgnoreTagNameDifferenceEvaluator(tagMap)));
user3718160
  • 481
  • 2
  • 11
  • 23