如何在XMLSlurper语句中使用变量引用 [英] How to I use a variable reference within XMLSlurper statement

查看:116
本文介绍了如何在XMLSlurper语句中使用变量引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有下面的代码可以工作(expectedResponse是var,用于存储期望的数据)

我使用XMLSlurper的groovy在soap ui pro中验证我的web服务响应。错误代码例如E0023)... $ /
$ b $ pre $ if(expectedResponse2 in slurper.Body.createShipmentResponse.integrationFooter.errors.error.errorCode.collect {it.text()})
{
result =pass
}

但我想用对SoapUI Pro数据源提供的变量的引用来替换'integrationFooter.errors.error.errorCode',因为我并不总是在相同的响应元素上进行验证。即如果我期待测试通过,我可能需要检查status元素是否填充了'Allocated'。如果我希望请求失败,我想验证errorCode字段是否填充了正确的errorCode,例如'E0023'。



如果我的groovyscript中有一个名为testElement的变量,并且为它指定元素的路径,例如integrationFooter.errors.error.errorCode我如何引用XMLSlurper语句中的变量?



我尝试了下面的代码,但没有奏效。

  if(expectedResponse2 in slurper.Body.createShipmentResponse。$ {testElement}。collect {it.text()})


解决方案

您需要分割字符串并依次处理每个属性。 ...

试试:

  def root = slurper.Body。 createShipmentResponse 
if(expectedResponse2 in testElement.tokenize('。').inject(root){v,p - >
v?。$ p
}?。collect {it。 text()}){
result =pass
}

使用[] 在groovy中访问对象属性

循环遍历 ['integrationFoo ter','errors','error','errorCode'] ,以 slurper.Body.createShipmentResponse 开头。所以第一次,注入返回 slurper.Body.createShipmentResponse.integrationFooter 。然后它在这个对象上调用 errors ,依此类推,直到获得可以调用 collect 的最终结果为止。
$ b ?。操作符意味着如果它碰到null(并返回null)给定一个这样的对象:

注解:



pre $ def obj = [prop1:[prop2:[prop3:'tim']]]

我们可以调用:

$ p $ assert obj.prop1.prop2.prop3 =='tim'

但是,如果我们将属性名称读为String:

  def props ='prop1.prop2.prop3'

然后这不起作用(因为没有关键'prop1.prop2.prop3'

  assert obj。$ props=='tim'// FAILS! 

但是我们可以在完整版中拆分 props 停止获取属性列表:

  def pList = props.tokenize('。')
assert pList = = ['prop1','prop2','prop3']

然后,我们可以通过这个列表,以 obj 开始:

  def result = pList.inject obj){currentObject,property  - > 
//从currentObject返回属性(如果currentObject为null,则返回null)
currentObject?。$ property
}
pList 中的每个元素,我们都这样做:


 第1步:
currentObject == obj
属性=='prop1'
返回obj.prop1 - [prop2:[prop3:'tim ']]

第2步:
currentObject == [prop2:[prop3:'tim']]
属性=='prop2'
返回currentObj.prop2 - - [prop3:'tim']

Step3(最后一步,因为pList现在已经结束了):
currentObject == [prop3:'tim']
property == 'prop3'
返回currentObj.prop3 - 'tim'

所以最终的结果是'tim'



希望这可以解释它: - )


I am using a groovy with XMLSlurper to validate my web service responses in soap ui pro.

I have the following code which works (expectedResponse is var that stores expected errorcode e.g. E0023) ...

if(expectedResponse2 in slurper.Body.createShipmentResponse.integrationFooter.errors.error.errorCode.collect{it.text()})
{
        result = "pass" 
}

But I would like to replace the 'integrationFooter.errors.error.errorCode' with a reference to a variable that I could supply from a SoapUI Pro datasource, because I am not always validating on the same response element. i.e if I am expecting the test to pass I might want to check that the status element is populated with 'Allocated'. If I am expecting the request to fail I want to validate that the errorCode field is populated with the correct errorCode e.g. 'E0023'.

If I have a variable called testElement in my groovyscript and I assign it the path of the element e.g. integrationFooter.errors.error.errorCode how do I refer to the variable within my XMLSlurper statement?

I tried the below code but it didn't work..

if(expectedResponse2 in slurper.Body.createShipmentResponse."${testElement}".collect{it.text()})

解决方案

You need to split the string and handle each property in turn yourself...

Try:

def root = slurper.Body.createShipmentResponse
if(expectedResponse2 in testElement.tokenize( '.' ).inject( root ) { v, p ->
                            v?."$p"
                        }?.collect{ it.text() } ) {
    result = "pass" 
}

See Access object properties in groovy using []

That loops over the list [ 'integrationFooter', 'errors', 'error', 'errorCode' ], starting with slurper.Body.createShipmentResponse. So first time round, the inject returns slurper.Body.createShipmentResponse.integrationFooter. Then it calls errors on this object, and so on until it gets the final result which you can call collect on.

The ?. operator just means it will keep going if it hits a null (and return null)

Inject explanation:

Given an object like this:

def obj = [ prop1:[ prop2:[ prop3: 'tim' ] ] ]

We can call:

assert obj.prop1.prop2.prop3 == 'tim'

However, if we were given the property name to read as a String:

def props = 'prop1.prop2.prop3'

Then this won't work (as there's no key 'prop1.prop2.prop3')

assert obj."$props" == 'tim'  // FAILS!

But we can split props on the full stop to get a list of properties:

def pList = props.tokenize( '.' )
assert pList == [ 'prop1', 'prop2', 'prop3' ]

Then, we can work through this list, starting with obj:

def result = pList.inject( obj ) { currentObject, property ->
    // Return the property from the currentObject (or null if currentObject is null)
    currentObject?."$property"
}

So for each element of pList, we do:

Step1:
    currentObject == obj
    property   == 'prop1'
    returns obj.prop1 -- [ prop2:[ prop3: 'tim' ] ]

Step2:
    currentObject == [ prop2:[ prop3: 'tim' ] ]
    property   == 'prop2'
    returns currentObj.prop2 -- [ prop3: 'tim' ]

Step3 (final step as pList is at an end now):
    currentObject == [ prop3: 'tim' ]
    property   == 'prop3'
    returns currentObj.prop3 -- 'tim'

So the final result is 'tim'

Hope this explains it :-)

这篇关于如何在XMLSlurper语句中使用变量引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆