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

how to get the attribute value inside cdata from the response and use it in other request

  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. 我想在另一个 request.Am 中使用 HIndex 值能够 select 另一个节点值。但是,当我 selecting 属性时,我得到 null

您可以使用 Groovy 脚本 testStep 来解析您的 SOAP testStep 响应。更确切地说,使用 XmlSlurper 来解析您的响应,通过标签名称在 slurper 中找到 CDATA,并再次解析 CDATA,因为 XmlSlurper returns CDATA 作为 String。最后通过名称找到所需的节点,然后使用 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 对象。
  • 要在其他 testSteps 中使用属性值,请将其保存在某个级别(例如 testCase testRunner.testCase.setPropertyValue('myAttrValue',hIndexValues[0].toString())),然后在其他 testStep 请求中使用 property expansion 符号 ${#TestCase#myAttrValue}.

如果您想在 Script Assertion 而不是 Groovy testStep 中使用上述脚本,您可以使用与上面相同的脚本只是改变了你从 testStep:

获得响应 Xml 的方式
// 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

这是第一个请求步骤的 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')

您可以快速尝试并执行来自 here 的脚本。