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

iOS Swift中JSON序列化未终止/无效字符串错误解决求助

解决iOS Swift中XML解析转JSON时的序列化错误

我之前也碰到过一模一样的问题!这种NSCocoaErrorDomain Code=3840的错误,本质上就是你从XML里拿到的字符串不符合JSON的语法规范,导致JSON解析器无法正常解析。咱们从几个常见的原因入手,一步步解决:

1. 首要问题:XML字符串包含JSON敏感未转义字符

JSON对字符串格式有严格要求,比如双引号、反斜杠、换行符这些字符必须被转义,否则会直接破坏JSON结构。比如XML里的内容是I love "Swift",直接把这个字符串放进JSON里就会导致引号不匹配,触发"Unterminated string"错误。

解决方案:转义JSON敏感字符

写一个通用的转义函数,在处理XML返回的字符串前先做转义:

func escapeStringForJSON(_ input: String) -> String {
    var escaped = input
    // 转义核心敏感字符
    escaped = escaped.replacingOccurrences(of: "\"", with: "\\\"")
    escaped = escaped.replacingOccurrences(of: "\\", with: "\\\\")
    // 处理换行、回车、制表符
    escaped = escaped.replacingOccurrences(of: "\n", with: "\\n")
    escaped = escaped.replacingOccurrences(of: "\r", with: "\\r")
    escaped = escaped.replacingOccurrences(of: "\t", with: "\\t")
    // 移除JSON不允许的控制字符(ASCII 0-31)
    let controlChars = CharacterSet.controlCharacters
    escaped = escaped.components(separatedBy: controlChars).joined()
    return escaped
}

2. XML解析时的字符串拼接不完整

foundCharacters方法不是一次性返回元素的全部内容,解析器可能会分多次返回字符片段。如果直接用单次返回的字符去转JSON,就会拿到不完整的字符串,触发"Garbage at end"错误。

解决方案:正确管理解析时的字符串拼接

在XML解析代理方法里,确保只有当元素解析完成时,才处理完整的字符串:

class XMLToJSONParserDelegate: NSObject, XMLParserDelegate {
    private var currentElementValue: String?
    
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        // 开始解析目标元素时,初始化空字符串
        if elementName == "你的目标元素名" {
            currentElementValue = ""
        }
    }
    
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        // 追加字符,而不是直接覆盖
        currentElementValue?.append(string)
    }
    
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        if elementName == "你的目标元素名", let rawString = currentElementValue {
            // 先转义,再构造JSON并序列化
            let escapedString = escapeStringForJSON(rawString)
            // 示例:构造包含该值的JSON对象
            let jsonString = "{\"result\": \"\(escapedString)\"}"
            
            guard let jsonData = jsonString.data(using: .utf8) else {
                print("字符串转Data失败")
                return
            }
            
            do {
                let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
                print("JSON解析成功:\(jsonObject)")
            } catch {
                print("JSON解析错误:\(error.localizedDescription)")
            }
            
            // 重置变量,避免影响下一个元素解析
            currentElementValue = nil
        }
    }
}

3. 额外检查:JSON结构是否合法

有时候错误不是来自字符串内容,而是你构造的JSON本身格式有误。比如少了闭合的引号、逗号,或者嵌套错误。建议在序列化前,先打印你构造的jsonString,手动检查是否符合JSON规范——比如有没有未闭合的引号,有没有多余的逗号等。

4. 特殊情况:CDATA段处理

如果你的XML里包含<![CDATA[...]]>块,虽然foundCharacters会返回CDATA内的内容,但CDATA里往往会包含更多特殊字符,同样需要用上面的转义函数处理,确保所有敏感字符都被转义后再序列化。

按照上面的步骤调整后,应该就能解决那些令人头疼的JSON序列化错误了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:12:27