从请求中提取 soap header 并将其添加到以下请求中

Extract soap header out of request and add it to following request

我正在尝试从 SoapUI 中的先前请求中提取 header,以便我可以在另一个请求中使用它。基本上,我想在一个 xml 中获取 Header 的节点值并将其插入到另一个 xml 的 header 值中。我试过使用 XMLSlurper 和 XMLParser 但没有得到我想要的。我可以从节点中提取文本,但需要实际的整个 header 值,以便可以根据需要将其插入到其他请求中。

text = testRunner.testCase.testSteps["ConversionRate"].testRequest.response.getRequestContent()
log.info text
def slurped = new XmlSlurper().parseText(text)
log.info slurped.Header

这会使用下面的 XML 示例生成 Value1Value2,但我想提取整个 header,所以它看起来像

<soapenv:Header>
<soapenv:MyTag>value1</soapenv:MyTag>
<soapenv:MyTag2>value2</soapenv:MyTag2>
</soapenv:Header>

用于此问题的样本 XML 如下

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:web="http://www.webserviceX.NET/">
<soapenv:Header>
<soapenv:MyTag>value1</soapenv:MyTag>
<soapenv:MyTag2>value2</soapenv:MyTag2>
</soapenv:Header>
<soapenv:Body>
  <web:ConversionRate>
     <web:FromCurrency>AFA</web:FromCurrency>
     <web:ToCurrency>ALL</web:ToCurrency>
  </web:ConversionRate>
</soapenv:Body>
</soapenv:Envelope>

获得值后,我需要将其作为 xml 样本插入 header,如下所示

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:web="http://www.webserviceX.NET/">
<soapenv:Header/>       
<soapenv:Body>
  <web:ConversionRate>
     <web:FromCurrency>AFA</web:FromCurrency>
     <web:ToCurrency>ALL</web:ToCurrency>
  </web:ConversionRate>
</soapenv:Body>
</soapenv:Envelope>

希望这是有道理的,关于如何在 xml 中获取 Header 的节点值并将其插入另一个 xml 的 header 值的任何建议都会不胜感激

谢谢

您没有使用附加 groovy 脚本来实现相同的目的。而是为第一个 SOAP 请求测试步骤添加 Script Assertion 和以下代码。

脚本:关注in-line条评论

//Define your element names to extract the data
def elements = ['MyTag', 'MyTag2']

//Don't modify anything beyond this point

//Check if the request is empty
assert context.request, 'Request is empty or null'

//Parse response
def xml = new XmlSlurper().parseText(context.request)

//Closure to find the element data
def getData = { element -> xml.'**'.find {it.name() == element}?.text() }

//Find the tag value and set the same as 
elements.each { context.testCase.setPropertyValue(it, getData(it)) }

在您要添加 headers 的下一个请求中进行以下更改。注意 headers 和 属性 扩展。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:web="http://www.webserviceX.NET/">
<soapenv:Header>
  <soapenv:MyTag>${#TestCase#MyTag}</soapenv:MyTag>
  <soapenv:MyTag2>${#TestCase#MyTag2}</soapenv:MyTag2>
</soapenv:Header>       
<soapenv:Body>
  <web:ConversionRate>
     <web:FromCurrency>AFA</web:FromCurrency>
     <web:ToCurrency>ALL</web:ToCurrency>
  </web:ConversionRate>
</soapenv:Body>
</soapenv:Envelope>

根据评论,添加以下内容作为答案。这是与另一个完全不同的解决方案。

  • 这是第一个请求测试步骤的脚本断言
  • 与其他解决方案不同,您不必定义元素名称
  • 脚本自动从第一个请求中读取 headers 并创建元素名称及其值的映射
  • 这还会读取下一个测试步骤请求并将上述步骤映射数据作为 headers 添加到 xml
  • 将更改 xml 更新到下一个测试步骤请求。

这是脚本断言(第一个测试步骤):您也可以关注 in-line 评论。

//Edit the name of the next test step name if required
def nextStepName = 'SOAP Request2'

//Check if the current request is empty
assert context.request, 'Request is empty or null'

def nextStep = context.testCase.testSteps[nextStepName]

log.info "Next step request before edit: ${nextStep.testRequest.requestContent}"

def getXml = { req -> new XmlSlurper().parseText(req) }
def getRequestHeaderMap = { x -> 
  def header = x.'**'.find {it.name() == 'Header'}
  header.children()*.name().collectEntries {[(it): header."$it".text()]} 
}


//Read and Parse current request and get headers as map
def currentRequestHeaders = getRequestHeaderMap(getXml(context.request))
log.info "Current request header parameters : $currentRequestHeaders"

//Read and Parse next step request
def nextRequest = getXml(nextStep.testRequest.requestContent)

//Remove existing headers
nextRequest.Header.replaceBody {}

//Update next request xml with current request headers 
currentRequestHeaders.collect { k, v -> nextRequest.Header.appendNode { "ns11:$k"('xmlns:ns11': 'http://schemas.xmlsoap.org/soap/envelope/', v) } }
def nextRequestString = groovy.xml.XmlUtil.serialize(nextRequest)

log.info "Updating next request with : $nextRequestString"

//Update next test step's request content
nextStep.testRequest.requestContent = nextRequestString