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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:19:39