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

在Swift中如何使用Alamofire解析非标准JSON数据?

解决思路与步骤

你遇到的是API返回了Swift/Objective-C字典的调试打印格式(非标准JSON),同时其中customerData字段是XML字符串。可以分两步解析:


1. 先提取外层的字段值

首先处理这个非标准的字典格式,有两种简单方式:

方式一:转成标准JSON手动处理

把打印的字符串做以下替换,转换成标准JSON:

  • 把所有=替换成:
  • 把所有;替换成,
  • 给所有键名(比如customerData、message)加上双引号

转换后的标准JSON如下:

{
    "customerData": "<zakaznik><zkznid>475301</zkznid><titul></titul><jmeno>757B746D</jmeno><prijmeni>DÁRKOVÁ KARTA</prijmeni><rozliseni></rozliseni><osloveniok>false</osloveniok><kontos></kontos><skupzak1_klic>DK</skupzak1_klic><skupzak2_klic>default</skupzak2_klic><cenkat_klic>1</cenkat_klic><platido>2118-07-31</platido><valid>true</valid></zakaznik>",
    "message": "Informace o zákazníkovi \"DÁRKOVÁ KARTA 757B746D\" načteny."
}

之后就可以用Swift自带的JSONSerialization或者Codable正常解析成字典。

方式二:用正则直接提取字段

如果不想转JSON,直接用正则表达式提取需要的内容:

let responseStr = """
{
    customerData = "<zakaznik><zkznid>475301</zkznid><titul></titul><jmeno>757B746D</jmeno><prijmeni>D\U00c1RKOV\U00c1 KARTA</prijmeni><rozliseni></rozliseni><osloveniok>false</osloveniok><kontos></kontos><skupzak1_klic>DK</skupzak1_klic><skupzak2_klic>default</skupzak2_klic><cenkat_klic>1</cenkat_klic><platido>2118-07-31</platido><valid>true</valid></zakaznik>";
    message = "Informace o z\U00e1kazn\U00edkovi \"D\U00c1RKOV\U00c1 KARTA 757B746D\" na\U010dteny.";
}
"""

// 提取customerData的XML内容
if let xmlRange = responseStr.range(of: #"customerData = "(.*?)";"#, options: .regularExpression) {
    let xmlStr = String(responseStr[xmlRange])
        .replacingOccurrences(of: #"customerData = ""#, with: "")
        .replacingOccurrences(of: """;""", with: "")
    // 拿到xmlStr后进入下一步解析XML
}

// 提取message内容
if let messageRange = responseStr.range(of: #"message = "(.*?)";"#, options: .regularExpression) {
    let message = String(responseStr[messageRange])
        .replacingOccurrences(of: #"message = ""#, with: "")
        .replacingOccurrences(of: """;""", with: "")
    print(message)
}

2. 解析customerData里的XML字符串

拿到XML字符串后,推荐用第三方库XMLCoder(基于Codable,用法和JSON解析一致),或者系统自带的XMLParser。

方式一:用XMLCoder(推荐)

  1. 先通过CocoaPods安装:
pod 'XMLCoder'
  1. 定义对应XML结构的Codable模型:
import XMLCoder

// 对应XML的<zakaznik>节点结构
struct Customer: Codable {
    let zkznid: String
    let titul: String?
    let jmeno: String
    let prijmeni: String
    let rozliseni: String?
    let osloveniok: String
    let kontos: String?
    let skupzak1_klic: String
    let skupzak2_klic: String
    let cenkat_klic: String
    let platido: String
    let valid: String
}

// 解析XML的方法
func parseCustomerXML(_ xmlStr: String) -> Customer? {
    guard let data = xmlStr.data(using: .utf8) else { return nil }
    do {
        let decoder = XMLDecoder()
        return try decoder.decode(Customer.self, from: data)
    } catch {
        print("XML解析失败: \(error)")
        return nil
    }
}
  1. 调用解析:
if let customer = parseCustomerXML(xmlStr) {
    print("用户ID: \(customer.zkznid)")
    print("姓名: \(customer.prijmeni) \(customer.jmeno)")
}

方式二:用系统XMLParser(无第三方依赖)

如果不想用第三方库,手动实现解析逻辑:

class CustomerParser: NSObject, XMLParserDelegate {
    private var currentElement = ""
    private var zkznid = ""
    private var jmeno = ""
    private var prijmeni = ""
    // 其他字段同理定义
    
    var result: Customer?
    
    func parse(xmlStr: String) {
        guard let data = xmlStr.data(using: .utf8) else { return }
        let parser = XMLParser(data: data)
        parser.delegate = self
        parser.parse()
    }
    
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        currentElement = elementName
    }
    
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else { return }
        switch currentElement {
        case "zkznid": zkznid += trimmed
        case "jmeno": jmeno += trimmed
        case "prijmeni": prijmeni += trimmed
        // 处理其他字段...
        default: break
        }
    }
    
    func parserDidEndDocument(_ parser: XMLParser) {
        result = Customer(
            zkznid: zkznid,
            titul: nil,
            jmeno: jmeno,
            prijmeni: prijmeni,
            rozliseni: nil,
            osloveniok: "",
            kontos: nil,
            skupzak1_klic: "",
            skupzak2_klic: "",
            cenkat_klic: "",
            platido: "",
            valid: ""
        )
    }
}

使用方式:

let parser = CustomerParser()
parser.parse(xmlStr: xmlStr)
if let customer = parser.result {
    print(customer.prijmeni)
}

额外建议

最好联系API开发者,让他们返回标准JSON格式,这样解析会更简单可靠,毕竟当前的返回格式只是调试用的打印格式,不是正式的API响应规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:49:56