Comparison failing while ignoring nodes

Help
Pablo
2010-08-27
2013-03-03
  • Pablo
    Pablo
    2010-08-27

    Hi. I have a problem when comparing two XMLs which should be similar (I'm using XMLUnit 1.3):

    XML1 is:
    <a>
      <b>
        <c1>1</c1>
        <c2>AAA</c2>
      </b>
      <b>
        <c1>2</c1>
        <c2>BBB</c2>
      </b>
    </a>

    XML2 is:
    <a>
      <b>
        <c1>4</c1>
        <c2>BBB</c2>
      </b>
      <b>
        <c1>3</c1>
        <c2>AAA</c2>
      </b>
    </a>

    As you can see the differences between XML1 and XML2 are:
      * The elements <b> are in a different order
      * The values of <c1> are unique.

    I am running a comparison which (I believe) IGNORES the values of <c1> therefore XML1 and XML2 should be treated as SIMILAR. I wrote a small code to show this:

    public class MainSmall {
        public static void main(String[] args) throws Exception {
            String xml1 = "<a><b><c1>1</c1><c2>AAA</c2></b><b><c1>2</c1><c2>BBB</c2></b></a>";
            String xml2 = "<a><b><c1>4</c1><c2>BBB</c2></b><b><c1>3</c1><c2>AAA</c2></b></a>";
            XMLUnit.setIgnoreAttributeOrder(true);
            XMLUnit.setIgnoreWhitespace(true);
            Diff diff = new Diff(xml1, xml2);
            diff.overrideDifferenceListener(new MyDifferenceListener());
            diff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
            boolean result = diff.similar();
            System.out.println("xml1 similar to xml2 : " + result);
        }
    }
    class MyDifferenceListener implements DifferenceListener {
        public int differenceFound(Difference difference) {
            Node controlNode = difference.getControlNodeDetail().getNode();
            String controlNodeParent = controlNode.getParentNode().getLocalName();
            if (controlNodeParent.equals("c1")) {
                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            }
            else {
                return RETURN_ACCEPT_DIFFERENCE;
            }
        }
        public void skippedComparison(Node arg0, Node arg1) {
        }
    }
    

    The output of running the above code is:

    xml1 similar to xml2 : false
    

    As you can see, it says that XML1 is NOT similar to XML2. Is there something wrong with my code? Could it be a bug?

    Thank you very much for your help.

     
  • Stefan Bodewig
    Stefan Bodewig
    2010-09-12

    Your problem is, you are not comparing the elements you think you are.

    RecursiveElementNameAndTextQualifier will still look at the c1 elements, even if the DifferenceListener ignores the differences.  It will see their nested texts never match and thus never select any elements to compare.  In default mode (compareUnmateched is true) XMLUnit picks the b elements in order - so you are not comparing the elements you intend to compare.

    To make it work you must also provide an ElementQualifier of your own that only looks at the nested text of the c2 nodes when matching b elements against each other.