如何从响应中获取cdata中的属性值并在其他请求中使用它

时间:2016-10-12 11:55:37

标签: groovy soapui cdata

  1. 这是我的回答,如何获取HIndex属性值?

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <HResponse xmlns="http://demo.org/">
            <HResult>
                <![CDATA[
                <HRS>
                    <Header>
                        <Currency>INR</Currency>
                        <SessionId>1313123123123123123</SessionId>
                    </Header>
                    <HotelDetails>
                        <Stay></Stay>
                        <Hotel HIndex="1701"  PrefContract="" HDIndex="28">
                            <HNm> Demo</HNm>
                            <HImg>demo</HImg>
                        </Hotel>
                       <Hotel HIndex="1702"  PrefContract="" HDIndex="29">
                            <HNm> Demo</HNm>
                            <HImg>demo</HImg>
                        </Hotel>
                        <Hotel HIndex="1703" PrefContract="" HDIndex="30">
                            <HNm> Demo</HNm>
                            <HImg>demo</HImg>
                        </Hotel>
                  </HotelDetails>
                </HRS>
              ]]>
            </HResult>
        </HResponse>
    </soap:Body>
    </soap:Envelope>
    
  2. 我想在另一个请求中使用HIndex值。能够选择其他节点值。但是,当我选择属性时,我得到null

2 个答案:

答案 0 :(得分:2)

您可以使用 Groovy脚本testStep 来解析SOAP testStep响应。更确切地说,使用XmlSlurper来解析您的回复,通过标记名称在slurper中获取CDATA个结果,并再次解析CDATA,因为XmlSlurper返回CDATAString。最后按名称查找所需节点,然后使用node.@attributeName表示法访问其属性值。这样的事情必须适合你的情况:

def xml = '''<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
    <HResponse xmlns="http://demo.org/">
        <HResult>
            <![CDATA[
            <HRS>
                <Header>
                    <Currency>INR</Currency>
                    <SessionId>1313123123123123123</SessionId>
                </Header>
                <HotelDetails>
                    <Stay></Stay>
                    <Hotel HIndex="1701"  PrefContract="" HDIndex="28">
                        <HNm> Demo</HNm>
                        <HImg>demo</HImg>
                    </Hotel>
                   <Hotel HIndex="1702"  PrefContract="" HDIndex="29">
                        <HNm> Demo</HNm>
                        <HImg>demo</HImg>
                    </Hotel>
                    <Hotel HIndex="1703" PrefContract="" HDIndex="30">
                        <HNm> Demo</HNm>
                        <HImg>demo</HImg>
                    </Hotel>
              </HotelDetails>
            </HRS>
          ]]>
        </HResult>
    </HResponse>
</soap:Body>
</soap:Envelope>'''

def slurper = new XmlSlurper().parseText(xml)
def cdataAsStr = slurper.'**'.find { it.name() == 'HResult' }.toString()
def cdataSlurper = new XmlSlurper().parseText(cdataAsStr)
// get all HIndex attribute values from `<Hotel>`
def hIndexValues = cdataSlurper.'**'.findAll { it.name() == 'Hotel' }*.@HIndex as List

备注

  • 在您的问题中,CDATA内的Xml格式不正确,请使用<Stay></Stay>代替<Stay></stay>(请注意小写)。
  • 如果您只对第一个<Hotel>的属性值感兴趣,请从列表中访问第一个元素:hIndexValues[0]
  • 如果您希望从SOAP testStep获取Xml内容,请使用以下代替String,而不是testRunner.testCase.getTestStepByName('TestStepName').getPropertyValue('response')def xml定义testRunner.testCase.setPropertyValue('myAttrValue',hIndexValues[0].toString())对象。
  • 要在其他testSteps中使用属性值,请将其保存在某个级别(例如testCase ${#TestCase#myAttrValue}),然后在其他testStep请求// in the script assertion you can access the // response from the current testStep simply with // messageExchange.getResponseContent() def xml = messageExchange.getResponseContent() def slurper = new XmlSlurper().parseText(xml) def cdataAsStr = slurper.'**'.find { it.name() == 'HResult' }.toString() def cdataSlurper = new XmlSlurper().parseText(cdataAsStr) // get all HIndex attribute values from `<Hotel>` def hIndexValues = cdataSlurper.'**'.findAll { it.name() == 'Hotel' }*.@HIndex as List 中使用property expansion表示法。

如果您想在脚本断言而不是 Groovy testStep 中使用上述脚本,您可以使用与上面相同的脚本,只更改获取方式从你的testStep响应Xml:

{{1}}

答案 1 :(得分:0)

以下是第一个请求步骤的Script Assertion。这将避免测试用例中的其他groovy脚本步骤。

请在线阅读相应的评论:

/**
 * This is Script Assertion for the first
 * request step which extracts cdata from response,
 * then HIndex'es from extracted cdata. And
 * Assigns first value at test case level, so that
 * it can be used in the rest of the test steps of
 * the same test case.
 * */

/**
* Closure to parse and retrieve the data
* retrieves element or attribute
*/
def searchData = { data, item, itemType ->
    def parsedData = new XmlSlurper().parseText(data)
    if ('attribute' == itemType) {
        return parsedData?.'**'.findAll{it.@"$item".text()}*.@"$item"
    }
    parsedData?.'**'.find { it.name() == item} as String
}

//Assert response xml
assert context.response, "Response data is empty or null"

//Get the CDATA from response which is inside of HResult
def cData = searchData(context.response, 'HResult', 'element')

//Assert retrieved CDATA is not empty
assert cData, "Data inside of HResult is empty or null"

//Get the HIndex list
def hIndexes = searchData(cData, 'HIndex', 'attribute')

//Print list of hIndexes
log.info hIndexes

//Print the first in the list
log.info "First HIndex is : ${hIndexes?.first()}"

//Print the last in the list
log.info "Last HIndex is : ${hIndexes?.last()}"

//Use the required HIndex from the list
context.testCase.setPropertyValue('HINDEX', hIndexes?.first().toString())
//or the below one using index
//context.testCase.setPropertyValue('HINDEX', hIndexes[0]?.toString())

在以下测试步骤中,您可以通过以下方式使用保存的HINDEX

  • 如果以下步骤是请求步骤(REST,SOAP,HTTP,JDBC等),则使用property expansion ${#TestCase#HINDEX},如<Index>${#TestCase#HINDEX}</Index>
  • 如果以下步骤是groovy脚本,则使用以下其中一项:
    context.expand('${#TestCase#HINDEX}')
    context.testCase.getPropertyValue('HINDEX')
    testRunner.testCase.getPropertyValue('HINDEX')

你可以快速尝试&amp;从here执行脚本。