目前,Apple 的 Codable 协议没有解码 XML 的方法。虽然 Plist 是 XML,但 XML 不一定是 Plist,除非它遵循某种格式。
虽然有很多第三方库,但我建议你看看XMLParsing library。该库包含一个 XMLDecoder 和一个 XMLEncoder,它们使用 Apple 自己的 Codable 协议,并且基于 Apple 的 JSONEncoder/JSONDecoder 并进行了更改以适应 XML标准。
链接:https://github.com/ShawnMoore/XMLParsing
W3School 要解析的 XML:
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
Swift Struct 符合 Codable:
struct Note: Codable {
var to: String
var from: String
var heading: String
var body: String
}
XML解码器:
let data = Data(forResource: "note", withExtension: "xml") else { return nil }
let decoder = XMLDecoder()
do {
let note = try decoder.decode(Note.self, from: data)
} catch {
print(error)
}
XML编码器:
let encoder = XMLEncoder()
do {
let data = try encoder.encode(self, withRootKey: "note")
print(String(data: data, encoding: .utf8))
} catch {
print(error)
}
与第三方协议相比,使用 Apple 的 Codable 协议有很多好处。举个例子,如果 Apple 决定开始支持 XML,你就不必重构了。
有关此库示例的完整列表,请参阅存储库中的 Sample XML 文件夹。
Apple 的解码器和编码器之间存在一些差异以符合 XML 标准。它们如下:
XMLDecoder 和 JSONDecoder 的区别
-
XMLDecoder.DateDecodingStrategy 有一个名为 keyFormatted 的额外案例。这种情况下需要一个为您提供 CodingKey 的闭包,您可以为所提供的密钥提供正确的 DateFormatter。这只是 JSONDecoder 的 DateDecodingStrategy 上的一个便利案例。
-
XMLDecoder.DataDecodingStrategy 有一个名为 keyFormatted 的额外案例。这种情况下需要一个为您提供 CodingKey 的闭包,您可以为所提供的密钥提供正确的数据或 nil。这只是 JSONDecoder 的 DataDecodingStrategy 上的一个便利案例。
- 如果符合 Codable 协议的对象有一个数组,并且正在解析的 XML 中不包含该数组元素,XMLDecoder 会为该属性分配一个空数组。这是因为 XML 标准规定,如果 XML 不包含该属性,则可能意味着这些元素为零。
XMLEncoder 和 JSONEncoder 的区别
包含一个名为StringEncodingStrategy的选项,这个枚举有两个选项,deferredToString和cdata。 deferredToString 选项是默认选项,会将字符串编码为简单字符串。如果选择cdata,所有的字符串都会被编码为CData。
encode 函数比 JSONEncoder 多了两个参数。函数中的第一个附加参数是一个 RootKey 字符串,它将整个 XML 包装在一个名为该键的元素中。此参数是必需的。第二个参数是一个XMLHeader,它是一个可选参数,可以带版本、编码策略和独立状态,如果你想在编码的xml中包含这些信息。