You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手求教:如何从指定SOAP响应中解析JSON数据?

刚接触SOAP API的话,从响应里提取JSON确实需要注意点小细节,我来帮你梳理下相关内容和具体的解析方法:

解析SOAP响应中的JSON数据入门

一、SOAP请求示例

这是你提供的请求包:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:name="http://www.example.org/Name"> 
  <soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:UsernameToken> 
        <wsse:Username>UODA_GUEST</wsse:Username> 
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">@password123</wsse:Password> 
      </wsse:UsernameToken> 
    </wsse:Security> 
  </soapenv:Header> 
  <soapenv:Body> 
    <Name> 
      <NATIONAL_ID>2135199186</NATIONAL_ID> 
      <SEC_KEY>1adb445f8815e450b25addad899cab156e63088c</SEC_KEY> 
      <LANG_CODE>ENG</LANG_CODE> 
      <SEC_CODE>@password123</SEC_CODE> 
    </Name> 
  </soapenv:Body> 
</soapenv:Envelope>

二、API信息

WSDL地址:http://pscstestserver.iau.edu.sa:8888/PSIGW/PeopleSoftServiceListeningConnector/U_COUNTRYLIST_ADM.1.wsdl

三、SOAP响应示例

注意这个响应的<soapenv:Body>中直接嵌入了JSON数组,这是我们需要提取的核心内容:

<?xml version="1.0" encoding="UTF-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
  <soapenv:Body>
    [{"nationalid":"2135199186","countrylist":[{"countryCode":"AFG","CountryName":"Afghanistan"},{"countryCode":"DZA","CountryName":"Algeria"},{"countryCode":"BHR","CountryName":"Bahrain"},{"countryCode":"COM","CountryName":"Comoros"},{"countryCode":"DJI","CountryName":"Djibouti"},{"countryCode":"EGY","CountryName":"Egypt"},{"countryCode":"ERI","CountryName":"Eritrea"},{"countryCode":"IRQ","CountryName":"Iraq"},{"countryCode":"JOR","CountryName":"Jordan"},{"countryCode":"KWT","CountryName":"Kuwait"},{"countryCode":"LBN","CountryName":"Lebanon"},{"countryCode":"LBY","CountryName":"Libyan Arab Jamahiriya"},{"countryCode":"MRT","CountryName":"Mauritania"},{"countryCode":"MAR","CountryName":"Morocco"},{"countryCode":"OMN","CountryName":"Oman"},{"countryCode":"PAK","CountryName":"Pakistan"},{"countryCode":"PSE","CountryName":"Palestinian Territory, Occupie"},{"countryCode":"QAT","CountryName":"Qatar"},{"countryCode":"SOM","CountryName":"Somalia"},{"countryCode":"SDN","CountryName":"Sudan"},{"countryCode":"SYR","CountryName":"Syrian Arab Republic"},{"countryCode":"TUN","CountryName":"Tunisia"},{"countryCode":"ARE","CountryName":"United Arab Emirates"},{"countryCode":"YEM","CountryName":"Yemen"}],"isError":false}]
  </soapenv:Body> 
</soapenv:Envelope>

四、你编写的Swift请求代码片段

看起来你的代码还没写完,先整理出来:

static func createServiceRequest(params : Dictionary<String,String>, serviceName:String, urlString: String, method: String) -> URLRequest { 
    var parameters : String = "" 
    for (key, param) in params { 
        parameters = "\(parameters)<\(key)>\(param)</\(key)>" 
    } 
    // 这里应该还有后续代码
}

五、具体解析步骤(Swift实现)

因为这个SOAP响应的Body里直接是JSON内容,所以我们需要先从XML里提取Body的文本,再把文本转换成JSON对象来解析。下面是原生Swift的实现示例:

1. 自定义XML解析代理提取Body内容

首先我们需要一个XMLParserDelegate的子类,专门用来抓取<soapenv:Body>中的文本内容:

class SOAPBodyParserDelegate: NSObject, XMLParserDelegate {
    private var currentElement = ""
    private(set) var bodyContent: String?
    private var isInsideBody = false
    
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        currentElement = elementName
        // 检测是否进入Body标签
        if elementName == "soapenv:Body" {
            isInsideBody = true
        }
    }
    
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        // 只收集Body标签内的文本
        if isInsideBody {
            let trimmedString = string.trimmingCharacters(in: .whitespacesAndNewlines)
            if !trimmedString.isEmpty {
                bodyContent = (bodyContent ?? "") + trimmedString
            }
        }
    }
    
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        // 退出Body标签时停止收集
        if elementName == "soapenv:Body" {
            isInsideBody = false
        }
    }
}

2. 完整的解析流程

接下来把XML解析和JSON解析结合起来,提取我们需要的数据:

func parseSOAPResponse(from data: Data) {
    // 1. 解析SOAP XML,提取Body内容
    let parser = XMLParser(data: data)
    let soapDelegate = SOAPBodyParserDelegate()
    parser.delegate = soapDelegate
    
    guard parser.parse(), let bodyText = soapDelegate.bodyContent else {
        print("Failed to extract content from SOAP Body")
        return
    }
    
    // 2. 将Body文本转换成Data,用于JSON解析
    guard let jsonData = bodyText.data(using: .utf8) else {
        print("Failed to convert Body text to Data")
        return
    }
    
    // 3. 解析JSON数据
    do {
        // 响应是一个JSON数组,先转成数组类型
        guard let responseArray = try JSONSerialization.jsonObject(with: jsonData) as? [[String: Any]] else {
            print("Response is not a valid JSON array")
            return
        }
        
        // 获取数组中的第一个元素(这里响应只有一个元素)
        guard let responseData = responseArray.first else {
            print("No data in response array")
            return
        }
        
        // 提取需要的字段
        if let nationalId = responseData["nationalid"] as? String {
            print("National ID: \(nationalId)")
        }
        
        if let countryList = responseData["countrylist"] as? [[String: String]] {
            print("\nCountry List:")
            countryList.forEach { country in
                let code = country["countryCode"] ?? "N/A"
                let name = country["CountryName"] ?? "N/A"
                print("\(code) - \(name)")
            }
        }
        
        if let isError = responseData["isError"] as? Bool {
            print("\nIs Error: \(isError)")
        }
        
    } catch {
        print("JSON parsing error: \(error.localizedDescription)")
    }
}

3. 使用说明

当你通过网络请求获取到SOAP响应的Data对象后,直接调用parseSOAPResponse(from: data)就可以完成解析了。如果你的网络请求用的是URLSession,可以在completionHandler里调用这个方法。


内容的提问来源于stack exchange,提问作者Badr Bujbara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:30:54