Duplicated comparison problem

Help
LaTruffe
2010-05-07
2013-03-03
  • LaTruffe

    LaTruffe - 2010-05-07

    Hello !

    I want to compare two xml nodes regardless of the their children order. Therefore, I use an ElementQalifier to identify the children to be compared (stop me if I'm wrong).
    But, in case of deep xml tree, the comparison of some node have to be done twice.

    Consider the following example:

    <node>
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
        </child>
        
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="anotherValue" />
            <grandchild att1="value" att2="value" />
        </child>
    <node>
    
    <node>
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="anotherValue" />
            <grandchild att1="value" att2="value" />
        </child>
        
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
        </child>
    <node>
    

    If I use the ElementNameQualifier provided as example, the comparison fail because the two first 'child' node are returned by the ElementNameQualifer (same name). To work properly, the ElementQualifier
    has to perform a deep comparison to identify the right child, and then, the comparator compares these two children again. This last comparison is useless.

    Is there a way to prevent this double comparison ?

    Thank by advance

    Best Regards

     
  • LaTruffe

    LaTruffe - 2010-05-07

    I put the example again… I can't edit my previous message to correct the BBCode…

    <node>
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
        </child>
        
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="anotherValue" />
            <grandchild att1="value" att2="value" />
        </child>
    <node>
    
    <node>
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="anotherValue" />
            <grandchild att1="value" att2="value" />
        </child>
        
        <child>
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
            <grandchild att1="value" att2="value" />
        </child>
    <node>
    
     
  • Stefan Bodewig

    Stefan Bodewig - 2010-05-07

    There is no built-in solution for your case, I'm afraid.  You'll probably have to code your own implementation of ElementQualifier.

    In order to match the node-Elements you'll likely need something similar to RecursiveElementNameAndTextQualifier but looking at attributes rather than nested texts - while you want an ElementNameQualifier for your remaining nodes.

    At least that's how I understand your needs.

    I'm not sure where a "second comparison" comes in.  ElementQualifier doesn't really perform a comparision itself - even if it technically does - it may well return two elements that XMLUnit later considers to be different.  So XMLUnit has to perform the comparison regardless.

    One thing to look out for is if you have unmatched elements.See XMLUnit.setCompareUnmatched introduced in XMLUnit 1.3.

     
  • LaTruffe

    LaTruffe - 2010-05-07

    Wow, very quick reply ! Thanks ! :)

    Actually, I made my own ElementQualifier which is recursive. My real problem is the double comparison:

    To identify the children to be compared, my ElementQualifier has to perform itself a comparison of the whole child xml trees (checking element name, attributes and cdata). Then, it returns the two elected children which are compared again by the comparator. This last comparison is redundant

    In my example, the comparator compares 'node'. Then, it iterates the 'child' nodes to find a node to be compared (using the ElementQualifier). My ElementQualifier do the following comparisons:
        - node1/child1 vs node2/child1 -> no match, the second grandchild has a difference in attribute values
        - node1/child1 vs node2/child2 -> MATCH !

    Then, the comparator compare node1/child1 vs node2/child2 and the comparison result is ok. But this comparison has been done twice, once in the ElementQualifier (to select the node), once in the comparator.

       
    I hope I'm understandable ! :)

     
  • Stefan Bodewig

    Stefan Bodewig - 2010-05-07

    very quick reply !

    Pure luck, I just happened to be working on XMLUnit anyway. 8-)

    What you see is what I ment, the difference engine doesn't know what kinds of comparisons the ElementQualifier has performed - and it is certainly legal to return matching elements that are different.

    Take ElementNameQualidier for example, the difference engine would still have to check attribute values or nested text.

    So there is no way around the double comparison as you see it, sorry.

     
  • LaTruffe

    LaTruffe - 2010-05-07

    I would like to suggest you a solution for fixing this problem.

    For now, XMLUnit behaves like that:
      - No ElementQualifier: select children in order, and compare
      - With ElementQualifier: iterate children and submit them to the ElementQualifier. If true, remove from child list and compare. If false, continue to iterate. (It's a bit simplified…)

    A solution would be to add a new mode:
      - No ElementQualifier + keep order mode: Same behavior as now (select nodes in order and compare)
      - No ElementQualifier + ignore order mode: iterate nodes, compare then. If comparison ok, remove from child list. If not ok, continue to iterate.
      - With ElementQualifier: same behavior as now.

    In fact, this new mode would behave like with the ElementQualifier. But, using the comparator itself to select nodes instead of the ElementQualifier.

    My 2 cents ! :)

     
  • Stefan Bodewig

    Stefan Bodewig - 2010-05-11

    Right now I'm redesigning the DifferenceEngine for XMLUnit 2.0 and your ideas may very well influence the outcome.

    With a modification like you suggest DifferenceListeners and ComparisionControlers could get notified of Differences that aren't actualy there (because a match is attempted and then discarded because there would be differences).

    For the difference engine of XMLUnit 2 that I envision evaluation of differences (are the pieces of XML equal, similar or different?) is already separate from collecting differences - if the API contract of the new interface DifferenceEvaluator clearly states that some Comparisions may actually get discarded this may be doable.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks