0
votes

I've this in script assertion

def holder = new XmlHolder( messageExchange.responseContentAsXml )

value of holder is

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <ns0:SOME_SEARCHResponse xmlns:ns0="urn:AA:BBB:CCC:some_WS">
         <ns0:some_ID>22222</ns0:Some_ID>
         <ns0:some_ID>33333</ns0:Some_ID>
         <ns0:Status>OK</ns0:Response>
...
...

below is assertions method, which is in a script lib

def assertions(xmlHolder, String... StringToAssert){

                StringToAssert.each{
               return xmlHolder.containsKey(StringToAssert)
               }
            }

I am calling assertions method like below from script assertion

assert true==context.Change.assertions(holder,"//ns0:Some_ID")

but receiving below error and I couldn't understand where the error is coming from.

net.sf.saxon.trans.XPathException: XPath syntax error at char 1 on line 2 in {\n[Ljava.lang.String}: Unexpected token "[" in path expression

EDIT Final version after @albciff comments looks like below

def assertions(xmlHolder,String... stringToAssert){
                  def results = stringToAssert.collect{ element ->
                  return xmlHolder.containsKey(element)
                }
                return results.every{it==true}
               //return results.contains(true)

            }
1
Variable names and parameter names are best starting with lower case letters - tim_yates
@tim_yates Thanks. I'll change. Any idea about the error. - user1207289
as @tim_yates says it's better to use a lower case letters to start the xml tags, however in this case I think that the problem comes from the assertions function. - albciff
I mean the parameter names, as in: String... StringToAssert - tim_yates
@tim_yates ops... right, but this not solve the problem isn't? maybe I'm misunderstanding something. - albciff

1 Answers

0
votes

The problem is in your assertions function definition, because instead of passing each element of the array StringToAssert individually, you're passing the whole array. This is why you get Unexpected token "[" in path expression because in your example xmlHolder.containsKey is receiving ["//ns0:Some_ID"] instead of //ns0:Some_ID, so the holder is trying to evaluate the [ from the array.

So you've to correct your function:

   StringToAssert.each{
       return xmlHolder.containsKey(StringToAssert)
   }

To something like:

   StringToAssert.each{ element ->
       // now you pass the element of the array instead the whole array
       return xmlHolder.containsKey(element)
   }

Or use collect to get all containsKey results in a list:

    def results = StringToAssert.collect{ elem ->
        return xmlHolder.containsKey(elem)
    }

Beside there is another problems in your code. Your XPath is incorrect, in your xml <some_ID> starts lower case however your XPath not "//ns0:Some_ID" an also since in your XPath ns0 prefix is not defined, better use * wildcard to match the node, so finally your XPath must be "//*:some_ID".

The last is in your assert, you're comparing the assertions function result against true:

assert true==context.Change.assertions(holder,"//ns0:Some_ID")

Since your assertions function doesn't return nothing, by default groovy returns the last object you use, in this case the parameter stringToAssert so really you're doing something like:

assert true==["//ns0:Some_ID"] 

This is why your assert fails. So change the return from assertions function.

If all the things are corrected the code could looks like:

import com.eviware.soapui.support.XmlHolder
def xml = '''<ns0:SOME_SEARCHResponse xmlns:ns0="urn:AA:BBB:CCC:some_WS">
         <ns0:some_ID>22222</ns0:some_ID>
         <ns0:some_ID>33333</ns0:some_ID>
         <ns0:Status>OK</ns0:Status>
     </ns0:SOME_SEARCHResponse>'''

def holder = new XmlHolder( xml )

def assertions(xmlHolder, String... stringToAssert){
    // check if xmlHolder contains at least one
    // element defined in the xpaths arrays
    def results = stringToAssert.collect{ elem ->
        return xmlHolder.containsKey(elem)
    }

     // if at least one xpath is satisfied returns true
    return results.contains(true)
}

assert true==holder.containsKey('//*:some_ID')

Hope it helps,