【问题标题】:Extracting JSON content from CDATA in SOAP Response从 SOAP 响应中的 CDATA 中提取 JSON 内容
【发布时间】:2016-04-27 07:11:31
【问题描述】:

我正在处理 SoapUI,我有一个 Soap 请求,它接受 Json 字符串格式的输入,处理后我得到一个 XML 格式的 Soap 响应,JSON 格式包含在 CDATA 中。

我正在尝试使用以下代码从 Soap Response 中提取数据,但出现错误“Prolog 中不允许内容”

import com.eviware.soapui.support.XmlHolder
import net.sf.json.groovy.JsonSlurper
import groovy.xml.Namespace

respXmlHolder = new XmlHolder(messageExchange.getResponseContentAsXml())
respXmlHolder.declareNamespace("ns1","http://tempuri.org/")
CDATAXml = respXmlHolder.getNodeValue("//ns1:ReportResult")
log.info(CDATAXml)


def data = new XmlParser().parseText(CDATAXml).Rpt
log info "data.findAll{it.'Name'}.size()"

Soap 响应如下所示:

<ReportResponse xmlns="http://tempuri.org/">
     <ReportResult><![CDATA[{
  "Report": [
    {
      "Name": "ABC",
      "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "",
     },
     {
      "Name": "EFG",
       "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "Manager",
     }
    ]
} ]]></ReportResult>
  </ReportResponse>
   </s:Body>
</s:Envelope>

请在这方面帮助我。

【问题讨论】:

  • 您正在尝试使用 xpath 获取 Result,但它在 xml 中的什么位置?可以看this类似的例子来提取json。
  • 你提到的例子有未包含在CDATA中的数据尝试提取但不起作用。

标签: soapui cdata web-api-testing


【解决方案1】:

正如 cmets 中的 @Rao 注释,您将 //ns1:Result 用作 XPath 但是此节点在您的响应中不存在。无论如何,作为替代而不是使用和XmlHolder,我打算首先使用XmlSlurper 解析SOAP 并获​​取CDATA 节点,然后使用JSonSlurper 解析包含在CDATA 并获得所需的值(在您的情况下,您似乎正在寻找 Name 值属性),请参见以下示例:

import groovy.json.JsonSlurper

def soapResponse = '''<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
<ReportResponse xmlns="http://tempuri.org/">
     <ReportResult><![CDATA[{
  "Report": [
    {
      "Name": "ABC",
      "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "",
     },
     {
      "Name": "EFG",
       "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "Manager",
     }
    ]
} ]]></ReportResult>
  </ReportResponse>
   </s:Body>
</s:Envelope>'''

// parse the soap
def xml = new XmlSlurper().parseText(soapResponse)
// get cdata node
def reportCDATA = xml.'**'.findAll{ it.name() == 'ReportResult' }
def jsonTxt = reportCDATA.pop().toString()
// parse CDATA value as JSON
def json = new JsonSlurper().parseText(jsonTxt)
// get the Name attribute values
def names = json.Report.collect { it.Name }
names.each { log.info it }

如果您在评论时想要获得"Completion Date" 而不是 JSON"Name" 值,您可以这样做:

def completionDates = json.Report.collect { it."Completion Date"}

或者如果看起来更清晰:

def completionDates = json.Report.collect { it[Completion Date] }

请注意,在您的示例中,Report 数组包含两个对象,它们都将null 作为"Completion Date" 的值。因此,使用您的 JSON 示例 def completionDates 将是 [null, null]

希望对你有帮助,

【讨论】:

  • 我得到以下代码的空结果: def names = json.Report.collect { it.Name } names.each { log.info it } 如果我想提取值完成日期我要这样提一下。“完成日期”??
  • 如果你得到空结果肯定是因为你的输入数据与示例中的数据不同,请检查XmlSlurperJsonSlurper中的路径正确性。要获取"Completion date",请查看更新后的回复:)
  • 是的,我已经尝试了以下 def Dates = json.Report.collect { it."Completion date"} 我在脚本断言中没有得到任何结果实际上我在 Report 数组中有超过 100 个对象。
  • 同意@albciff,问题中提供的数据没有Completion Date 的数据。例如,如果您选择Due Date,则会列出可以在screen shot 中看到的日期。此外,SDhwaj 使用了不正确的属性名称,即使用Completion date 而不是Completion Date。请尝试更正它。
  • 查找不正确大小写的复制粘贴问题。第一条评论的大小写错误,@albciff 在提供的脚本中使用了错误的大小写,并被另一个评论复制,反之亦然。
猜你喜欢
  • 2015-01-29
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
  • 2014-06-03
  • 1970-01-01
  • 2012-10-23
  • 2018-04-10
  • 1970-01-01
相关资源
最近更新 更多