Search code examples
xmlgroovycomparexmlunitxmlunit-2

Groovy : Compare SOAP Response with XML file


I want to compare in groovy code my Soap Response with xml file ignoring order :

Here is my code :

import org.custommonkey.xmlunit.Stuff
import org.xmlunit.Stuff

//ExpectedString is my xml converted to text, same for ResponseString

Diff diff = DiffBuilder.compare(ExpectedString)
           .withTest(ResponseString)
           .ignoreComments()
           .ignoreWhitespace()
           .checkForSimilar()
           .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName))
           .build();

assertFalse("XML similar " + diff.toString(), diff.hasDifferences())

So, as you can see, I used DefaultNodeMatcher, I used XMLUnit2.0 ... with no result (even not ignoring order or having exception error while comparing)

Is there a solution ? to resolve this

As I'm desperate to find a direct one, can I sort my xml and my soap response so i can have a simple diff ? is there a way to sort it line by line alphabetically ? If yes, how ?

Thank you guys !

Update :

Here is my XML structure simplified

<body>
<stuff>
  <miniStuff></miniStuff>
  <miniStuff></miniStuff>
</stuff>
<Services>
  <Service>
    <tag1>ValueA</tag1>
    <tag2>ValueAA</tag2>
  </Service>
  <Service>
    <tag1>ValueB</tag1>
    <tag2>ValueBB</tag2>
  </Service>
</services>
</body>

My problem is I can't guarantee that ValueA is the first one and not the second


Solution

  • Here is the one you might looking for: use ByNameAndTextRecSelector

    withNodeMatcher(new DefaultNodeMatcher(new ByNameAndTextRecSelector(),ElementSelectors.byName))
    

    Unit Test:

        @Test
        public void testDiffOrder() {
            final String control = """
                <r>
                    <ser>
                        <t1>a</t1>
                        <t2>b</t2>
                    </ser>
                    <ser>
                        <t1>d</t1>
                        <t2>e</t2>
                    </ser>
                </r>"""
            final String test = """
                <r>
                    <ser>
                        <t1>d</t1>
                        <t2>e</t2>
                    </ser>
                    <ser>
                        <t1>a</t1>
                        <t2>b</t2>
                    </ser>
                </r>"""
            Diff diff = DiffBuilder.compare(Input.fromString(control))
                    .withTest(Input.fromString(test))
                    .ignoreComments()
                    .ignoreWhitespace()
                    .checkForSimilar()
                    .withNodeMatcher(new DefaultNodeMatcher(new ByNameAndTextRecSelector(),ElementSelectors.byName))
                    .build()
    
            assertFalse("XML differ " + diff.toString(), diff.hasDifferences())
        }
    

    Credits to @bodewig. Sample from here

    UPDATE: more groovified versionwith OPs original xml snippet.

    import org.xmlunit.builder.DiffBuilder
    import org.xmlunit.builder.Input
    import org.xmlunit.diff.ByNameAndTextRecSelector
    import org.xmlunit.diff.DefaultNodeMatcher
    import org.xmlunit.diff.ElementSelectors
    
    def control = """<body>
       <stuff>
          <miniStuff />
          <miniStuff />
       </stuff>
       <Services>
          <Service>
             <tag1>ValueB</tag1>
             <tag2>ValueBB</tag2>
          </Service>
          <Service>
             <tag1>ValueA</tag1>
             <tag2>ValueAA</tag2>
          </Service>
       </Services>
    </body>"""
    def test = """<body>
       <stuff>
          <miniStuff />
          <miniStuff />
       </stuff>
       <Services>
          <Service>
             <tag1>ValueA</tag1>
             <tag2>ValueAA</tag2>
          </Service>
          <Service>
             <tag1>ValueB</tag1>
             <tag2>ValueBB</tag2>
          </Service>
       </Services>
    </body>"""
    def myDiff = DiffBuilder.compare(Input.fromString(control))
                .withTest(Input.fromString(test))
                .checkForSimilar()
                .withNodeMatcher(new DefaultNodeMatcher(new ByNameAndTextRecSelector(),ElementSelectors.byName))
                .build()
    println myDiff.toString()
    println myDiff.hasDifferences()
    assert !myDiff.hasDifferences()