如何在XMLSlurper语句中使用变量引用

时间:2014-01-14 15:01:51

标签: groovy soapui xmlslurper

我正在使用XMLSlurper的groovy来验证我在soap ui pro中的Web服务响应。

我有以下代码可用(expectedResponse是存储预期错误代码的var,例如E0023)...

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

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

如果我的groovyscript中有一个名为testElement的变量,我将它分配给元素的路径,例如: integrationFooter.errors.error.errorCode如何在XMLSlurper语句中引用变量?

我尝试了下面的代码,但它没有用。

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

1 个答案:

答案 0 :(得分:1)

你需要拆分字符串并依次处理每个属性......

尝试:

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

请参阅Access object properties in groovy using []

[ 'integrationFooter', 'errors', 'error', 'errorCode' ]开始循环遍历列表slurper.Body.createShipmentResponse。所以第一次,注入返回slurper.Body.createShipmentResponse.integrationFooter。然后它会在此对象上调用errors,依此类推,直到获得最终结果,您可以调用collect

?.运算符只是意味着它会在遇到null时继续运行(并返回null)

注入说明:

给出这样一个对象:

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

我们可以致电:

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

但是,如果我们将属性名称作为字符串读取:

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 ->
    // Return the property from the currentObject (or null if currentObject is null)
    currentObject?."$property"
}

因此,对于pList的每个元素,我们执行:

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'

所以最终的结果是'tim'

希望这能解释它: - )