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.
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 ! :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 ! :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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
I put the example again… I can't edit my previous message to correct the BBCode…
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.
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 ! :)
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.
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 ! :)
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.