且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Swift4中的Codable和XMLParser

更新时间:2022-06-12 22:52:15

当前,Apple的 Codable 协议没有办法

Currently, Apple's Codable protocol does not have a way to decode XML.

尽管有很多第三方库可以解析XML,但 XMLParsing库包含一个 XMLDecoder 和一个使用Apple自己的 Codable 协议并基于Apple的 XMLEncoder JSONEncoder / JSONDecoder,并进行了更改以适合XML标准。

While there are plenty of third party libraries to parse XML, the XMLParsing library contains a XMLDecoder and a XMLEncoder that uses Apple's own Codable protocol, and is based on Apple's JSONEncoder/JSONDecoder with changes to fit the XML standard.

链接: 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>

符合Codable的Swift Struct:

struct Note: Codable {
    var to: String
    var from: String
    var heading: String
    var body: String
}

XMLDecoder:

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)
}

XMLEncoder:

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,则不必进行重构。

There are a number of benefits for using Apple's Codable protocol over that of a third-party's protocol. Take for example if Apple decides to begin supporting XML, you would not have to refactor.

有关该库示例的完整列表,请参见

For a full list of examples of this library, see the Sample XML folder in the repository.

Apple的解码器和编码器之间有一些区别,以适应XML标准。这些是:

There are a few differences between Apple's Decoders and Encoders to fit the XML standard. These are as follows:

XMLDecoder和JSONDecoder之间的差异


  1. XMLDecoder.DateDecodingStrategy 有一个额外的案例,标题为 keyFormatted 。这种情况下需要给您一个CodingKey一个闭包,由您来为所提供的密钥提供正确的DateFormatter。这只是JSONDecoder的 DateDecodingStrategy 上的一种方便情况。

  2. XMLDecoder.DataDecodingStrategy 有一个额外的情况。标题为 keyFormatted 。这种情况下需要给您提供CodingKey的闭包,由您决定是否为提供的密钥提供正确的数据或nil。这只是JSONDecoder的 DataDecodingStrategy 上的一种方便情况。

  3. 如果符合Codable协议的对象具有数组,并且所解析的XML不包含数组元素,XMLDecoder将为属性分配一个空数组。这是因为XML标准规定如果XML不包含该属性,则可能意味着这些元素为零。

  1. XMLDecoder.DateDecodingStrategy has an extra case titled keyFormatted. This case takes a closure that gives you a CodingKey, and it is up to you to provide the correct DateFormatter for the provided key. This is simply a convenience case on the DateDecodingStrategy of JSONDecoder.
  2. XMLDecoder.DataDecodingStrategy has an extra case titled keyFormatted. This case takes a closure that gives you a CodingKey, and it is up to you to provide the correct data or nil for the provided key. This is simply a convenience case on the DataDecodingStrategy of JSONDecoder.
  3. If the object conforming to the Codable protocol has an array, and the XML being parsed does not contain the array element, XMLDecoder will assign an empty array to the attribute. This is because the XML standard says if the XML does not contain the attribute, that could mean that there are zero of those elements.

XMLEncoder和JSONEncoder之间的差异


  1. 包含一个名为 StringEncodingStrategy的选项,此枚举有两个选项, deferredToString cdata deferredToString 选项是默认选项,会将字符串编码为简单字符串。如果选择 cdata ,则所有字符串都将编码为CData。

  1. Contains an option called StringEncodingStrategy, this enum has two options, deferredToString and cdata. The deferredToString option is default and will encode strings as simple strings. If cdata is selected, all strings will be encoded as CData.

编码函数比JSONEncoder接受两个附加参数。函数中的第一个附加参数是 RootKey 字符串,该字符串会将整个XML包裹在名为该键的元素中。此参数是必需的。第二个参数是XMLHeader,如果要在编码的xml中包含此信息,则它是一个可选参数,可以采用版本,编码策略和独立状态。

The encode function takes in two additional parameters than JSONEncoder does. The first additional parameter in the function is a RootKey string that will have the entire XML wrapped in an element named that key. This parameter is required. The second parameter is an XMLHeader, which is an optional parameter that can take the version, encoding strategy and standalone status, if you want to include this information in the encoded xml.