新手求教:如何从指定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
相关产品推荐
相关产品推荐

