XMLCoder 不能直接用 Codable 解析任意 XML,因其仅支持结构清晰、可映射为 Swift 类型层次的 XML,不支持混合内容、PI、DTD、注释、默认命名空间等;需用 XMLText 处理纯文本节点,数组自动聚合同名元素,可选字段和嵌套结构按 Codable 规则处理。

XMLCoder 不能直接用 Codable 解析任意 XML
Swift 原生 Codable 协议只支持 JSON(通过 JSONEncoder/JSONDecoder),不支持 XML。XMLCoder 是第三方库,它**扩展了 Decoder 和 Encoder 协议**,让 Codable 类型能被用于 XML 编解码,但前提是 XML 结构必须能映射为 Swift 的类型层次 —— 它不是通用 XML 解析器(比如不能处理混合内容、PI、DTD 或任意嵌套文本节点)。
- 它要求 XML 有清晰的层级结构,标签名与属性名需对应 Swift 属性名(或通过
@XMLKey显式标注) - 不支持 XML 注释、处理指令、命名空间(除非手动配置
XMLDecoder.KeyEncodingStrategy或自定义KeyedDecodingContainer) - 默认把 XML 属性(
attr="value")映射为 Swift 属性,把子元素映射为嵌套结构;文本内容需显式声明为XMLText类型
基础用法:定义 Codable 类型 + XMLDecoder.decode(_:from:)
先用 Swift 包管理器添加依赖:https://github.com/MaxDesiatov/XMLCoder,然后定义符合 Codable 的结构体。注意:XML 标签名和 Swift 属性名默认按 snake_case ↔ kebab-case 自动转换(如 user_name ↔ user-name),可通过 keyEncodingStrategy 调整。
import XMLCoder
struct User: Codable {
let id: Int
let name: String
let isActive: Bool
enum CodingKeys: String, CodingKey {
case id = "user-id"
case name = "full-name"
case isActive = "active"
}
}
let xml = """
Alice
true
"""
do {
let user = try XMLDecoder().decode(User.self, from: xml.data(using: .utf8)!)
print(user.id) // 123
} catch {
print("Decode failed:", error)
}
解析带文本内容的元素(如 9.99 )
如果 XML 元素只有纯文本(无子元素、无属性),必须用 XMLText 类型声明,否则解码会失败 —— 这是新手最常踩的坑。
- 错误写法:
let price: Double→ 解码报错Expected element but found text - 正确写法:
let price: XMLText,或更安全地用XMLText再手动转
struct Product: Codable {
let name: String
let price: XMLText // ← 必须用 XMLText 包裹
}
let xml = "Book 19.99 "
let product = try XMLDecoder().decode(Product.self, from: xml.data(using: .utf8)!)
print(product.price.value) // 19.99
处理可选字段、数组、嵌套结构
数组对应多个同名子元素(如 ),可选字段用 ?,嵌套结构直接用另一个 Codable 类型。XMLCoder 默认将重复元素自动聚合成数组,无需额外标注。
- 空元素(
)会被解码为[](如果类型是[String]) - 缺失元素默认为
nil(如果属性是可选型),否则触发解码错误 - 若想忽略缺失字段而不报错,可设
decoder.keyNotFoundDecodingStrategy = .convertToNil
struct Order: Codable {
let id: Int
let items: [Item]
let notes: String?
}
struct Item: Codable {
let sku: String
let qty: XMLText
}
let xml = """
ABC 2
XYZ 1
Urgent
"""
let order = try XMLDecoder().decode(Order.self, from: xml.data(using: .utf8)!) // items 自动成数组
XMLCoder 对命名空间、CDATA、属性与文本共存的支持较弱,真遇到这类复杂 XML,不如用 XMLParser(SAX)或 SWXMLHash(DOM 风格)更可控。










