Swift中如何将SOAP字符串响应转换为JSON?
搞定Swift中SOAP响应转JSON的难题
嘿,我知道处理SOAP响应转JSON的时候很容易踩坑,尤其是当JSON藏在SOAP的XML结构里的时候。我帮你梳理下解决步骤,一步步来:
第一步:先把纯净的JSON从SOAP XML里抠出来
SOAP响应本质是XML格式,你拿到的JSON数组肯定是嵌套在XML的某个节点里的,比如可能是<GetStudentGradesResult>这种节点的文本内容。你可不能直接拿整个SOAP XML字符串去转JSON,那肯定会失败的!
举个例子,假设你的SOAP响应长这样:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <GetStudentGradesResponse> <GetStudentGradesResult>[{"StudentId":1526,"SchoolCode":"21013",...}]</GetStudentGradesResult> </GetStudentGradesResponse> </soap:Body> </soap:Envelope>
你得先把<GetStudentGradesResult>里面的那段JSON字符串提取出来。Swift里可以用XMLParser自己写解析逻辑,或者用第三方库SWXMLHash来简化,代码大概是这样:
import SWXMLHash // 假设soapResponseString是完整的SOAP XML响应 let xml = SWXMLHash.parse(soapResponseString) // 这里的节点路径要跟你的SOAP响应结构对应,别写错了! if let jsonString = xml["soap:Envelope"]["soap:Body"]["GetStudentGradesResponse"]["GetStudentGradesResult"].element?.text { // 终于拿到纯净的JSON字符串啦 print(jsonString) }
第二步:先确认你的JSON字符串是完整且合法的
你给的示例字符串末尾是Instructo...,这明显是截断了!不完整的JSON肯定解析失败啊。先把拿到的JSON字符串复制到JSON校验工具里检查下:
- 有没有漏写闭合的
}或者]? - 布尔值是不是小写的
true/false?JSON要求必须小写,大写的TRUE会报错 - 空值是不是
null?符合JSON规范才行
确保JSON格式完全正确了再往下走。
第三步:把JSON字符串转成Swift对象
这一步有两种常用方法,推荐用类型安全的Codable,但也给你写传统的JSONSerialization方法:
方法一:用Codable(更靠谱,类型安全)
先定义对应的数据模型,把JSON里的字段都映射好:
struct StudentGrade: Codable { let studentId: Int let schoolCode: String let academicPeriod: String let classBranch: String let courseId: Int let courseName: String let isNumber: Bool let homeWork1: Int let midterm1: Int let final1: Int let grade1: Int let homeWork2: Int let midterm2: Int let final2: Int let grade2: Int let notes1: String? let notes2: String? // 因为JSON里的键是大驼峰(比如StudentId),Swift里用小驼峰,所以要做映射 enum CodingKeys: String, CodingKey { case studentId = "StudentId" case schoolCode = "SchoolCode" case academicPeriod = "AcademicPeriod" case classBranch = "ClassBranch" case courseId = "CourseId" case courseName = "CourseName" case isNumber = "IsNumber" case homeWork1 = "HomeWork1" case midterm1 = "Midterm1" case final1 = "Final1" case grade1 = "Grade1" case homeWork2 = "HomeWork2" case midterm2 = "Midterm2" case final2 = "Final2" case grade2 = "Grade2" case notes1 = "Notes1" case notes2 = "Notes2" } }
然后解析:
guard let jsonData = jsonString.data(using: .utf8) else { print("哎呀,字符串转Data失败了") return } do { let studentGrades = try JSONDecoder().decode([StudentGrade].self, from: jsonData) // 现在可以愉快地用解析后的数组啦 for grade in studentGrades { print("课程:\(grade.courseName),第一次期末成绩:\(grade.final1)") } } catch { print("解析出错啦:\(error.localizedDescription)") }
方法二:用JSONSerialization(灵活但不安全)
如果不想写模型,也可以用这个方法:
guard let jsonData = jsonString.data(using: .utf8) else { print("字符串转Data失败") return } do { if let jsonArray = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [[String: Any]] { // 遍历数组处理每个学生的数据 for student in jsonArray { let studentId = student["StudentId"] as? Int let schoolCode = student["SchoolCode"] as? String print("学生ID:\(studentId ?? 0),学校代码:\(schoolCode ?? "")") } } } catch { print("JSON解析失败:\(error.localizedDescription)") }
常见坑点排查
- 没提取纯净JSON:直接拿整个SOAP XML转JSON,肯定失败,必须先抠出XML里的JSON文本
- JSON不完整/格式错:比如截断、引号不匹配、布尔值大写,先校验JSON格式
- 编码问题:转Data的时候用
.utf8,如果SOAP响应有特殊编码,要对应调整
内容的提问来源于stack exchange,提问作者mentis
相关产品推荐
相关产品推荐

