Groovy : XML Comparison: Dynamic XML Attributes are not ignored whie comparison.
SOLVED- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Groovy : XML Comparison: Dynamic XML Attributes are not ignored whie comparison.
Hi
I have one Groovy utility to compare current response with external response kept in xml file.
But while comparison, I am facing issue if parameter contains space. e.g.
1. If parameter is present as , subscription id .Then it is not ignored
2. If parameter is present as, subscription-id. Then it is ignored while comparison. Working file.
My case:
Actually in my case, subscription id will be dynamic. So while comparison , I added it in ignore list. So that next time this will be ignored while comparison.
Attached my groovy Utility and sample external response file.
Regards
Vishal
Solved! Go to Solution.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi nmrao
1. While comparison, there are some dynamic parameters. e.g. subscription id, purchase-date, expiry-date. So I add them in ignore list.
Issue:
1. Able to ignore xml elements like purchase-date, expiry-date while comparison. Which is fine.
But not able to ignore attributes. e.g. for subscription, 'id' is attribute. And not able to ignore it.
So question is hot to ignore attribute values while xml comparison.
Note: Attached my actual responses and Groovy utility. PFA
Can you please have a look into it. Actually I am really struggling around this.
Regards
Vishal Pachpute
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not sure if you got my request, as requested info is not available. Note that you do not have to provide your exact data, just resembling your case, so that you could implement based on example solution if at all solution posted.
EDIT
looks like, this time added some more elements in the responses.
NOTE: While adding file, have some file extension.
By the way, you posted both same responses. Not sure if that is copy-paste. Hoping that what you posted are more nearistic to your data. Post the responses that you have problem while comparing.
Regards,
Rao.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
Sorry, By mistake I copy-pasted twice.
But there is no issue. As I mentioned there are only following 3 dynamic parameters values will be different. You can also change these 3 parameters values at your end.
subscription id, purchase-date, expiry-date
I have changed these 3 parameters and added file extension. (Actually working on Ubuntu so it was plain file)
Issue:
1. Able to ignore xml elements like purchase-date, expiry-date while comparison. Which is fine.
But not able to ignore attributes. e.g. for subscription, 'id' is attribute. And not able to ignore it.
So question is hot to ignore attribute values while xml comparison.
PFA.
Regards
Vishal
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The data provided is not well-formed. Fixed a bit to make it well-formed.
Here is the script:
//assign xml string data for the below two statements, not assigned here to reduce the size of the script def expected = def actual = //Don't have to modify beyond this point //If required, add more ignore nodes or attributes(node: attribute format) in the below appropriately def ignoreNodes = ['purchase-date', 'expiry-date'] def ignoreAttributes = ['subscription':'id'] //Closure to update the xml with a fixed value REPLACED in place of dynamic value, so that comparison is done successfully def updateIgnoreElements = { data, fixedVal = 'REPLACED' -> def parsedData = new XmlSlurper().parseText(data) ignoreAttributes.each { k,v -> parsedData.'**'.findAll { it.name() == k}.collect{it.@"$v" = fixedVal} } ignoreNodes.each { element -> parsedData.'**'.findAll { it.name() == element}.collect{it.replaceBody fixedVal} } groovy.xml.XmlUtil.serialize(parsedData) } assert updateIgnoreElements(expected) == updateIgnoreElements(actual), 'Both are not matching'
You can quickly try online demo and the same is available at github
Regards,
Rao.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@vpachpute1, if the right information is provided along with the problem statement in the beginning, it might not have to wait so long. Any ways, glad it helped.
Adding kudoes for the helpful posts is appreciated.
Regards,
Rao.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I hope you don't mind me coming back to this issue, as it kind of piqued my interest.
Firstly I always felt a bit uncomfortable with the idea of altering the response XML to make the comparison, and secondly I noticed in you were using a third party library XMLUnit. This is something I had not come across before your post, and was unable to research at the time of answering your question, but since then have had time to investigate.
From the XMLUnit web page: "The most important part is a diff-engine that provides you with full control over what kind of difference is important to you and which part of the generated document to compare with which part of your reference document."
Seeing as you had already gone to the trouble of installing the XMLUnit libraries, and were using the diff engine, I thought there should be a way of leveraging the XMLUnit functionality to do what you wanted.
The following code answers your original question, without having to resort to hacking your response XML. What I really like is that (and I hope you'll agree) it that the code is very readable and you can easily understand what the intention is. I must admit that with your original code, to me it was not very obvious what the intent was.
import javax.xml.transform.Source import org.w3c.dom.Attr import org.w3c.dom.Node import org.xmlunit.builder.DiffBuilder import org.xmlunit.builder.Input import org.xmlunit.util.Predicate // Fixed control XML to compare responses too. def controlXmlText = '''<response> <payload> <selfcare> <subscription id="2306" status="24"> <charging-method>3</charging-method> <duration-code>2</duration-code> <rate resource="GBP" tax-rate="0.185">2.37</rate> <pricepoint/> <purchase-date>2017-04-18T14:12:39+05:30</purchase-date> <expiry-date>2017-04-25T23:59:59+05:30</expiry-date> <package-id>ReservedPackage</package-id> <b2b-partner> <id>B2B_Google</id> </b2b-partner> <partner-id>B2B_Google</partner-id> </subscription> </selfcare> </payload> </response>''' // Response XML has differences in the two date elements and the id attributes, which // are ignored by the filters below, edit other elements and attributes to see the // assertion below identify other differences. def responseXmlText = '''<response> <payload> <selfcare> <subscription id="2310" status="24"> <charging-method>3</charging-method> <duration-code>2</duration-code> <rate resource="GBP" tax-rate="0.185">2.37</rate> <pricepoint/> <purchase-date>2017-04-19T14:12:39+06:30</purchase-date> <expiry-date>2017-04-26T23:59:59+06:30</expiry-date> <package-id>ReservedPackage</package-id> <b2b-partner> <id>B2B_Google</id> </b2b-partner> <partner-id>B2B_Google</partner-id> </subscription> </selfcare> </payload> </response>''' // Control and response sources, this demo is just from text strings, See: // http://www.xmlunit.org/api/java/2.3.0/org/xmlunit/builder/Input.html // For details of all other input source. def controlXml = Input.from(controlXmlText).build(); def responseXml = Input.from(responseXmlText).build(); def nodeFilter = new Predicate<Node>() { public boolean test(Node element) { // List of element names to ignore. def elementsToIgnore = ['purchase-date', 'expiry-date'] return !elementsToIgnore.contains(element.getLocalName()) } } def attributeFilter = new Predicate<Attr>() { public boolean test(Attr attribute) { // List of attributes names to ignore (regardless of element). def attributesToIgnore = ['id'] return !attributesToIgnore.contains(attribute.getLocalName()) } } def diff = DiffBuilder.compare(controlXml) .withTest(responseXml) .withNodeFilter(nodeFilter) .withAttributeFilter(attributeFilter) .ignoreComments() .ignoreWhitespace() .build() assert !diff.hasDifferences()
I was really just investigating XMLUnit for my own interest, but I thought I'd post back here what I found as someone might find it useful. If so here is the user guide and javadocs.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Radford
I really appreciate your efforts for my issue.
Thanks a lot. I will try this solution and let you know by this weekend.
Thanks
Vishal

- « Previous
-
- 1
- 2
- Next »
- « Previous
-
- 1
- 2
- Next »