使用新的Swift4 typealiase“Codable”适用于JSON解码(如here或here或许多其他贡献所述).但是,在XML解析方面,我找不到任何有关此“Codable”协议是否也可用于XML解码的信息.
我尝试使用XMLParser(可以在下面的代码中看到).但我没有使用“Codable”协议来简化XML解析过程.我怎么必须完全使用Codable协议来简化XML解析?
// the Fetching of the XML-data (excert shown here with a simple dataTask) : let myTask = session.dataTask(with: myRequest) { (data,response,error) in // check for error guard error == nil else { completionHandler(nil,error!) return } // make sure we got data in the response guard let responseData = data else { let error = XMLFetchError.objectSerialization(reason: "No data in response") completionHandler(nil,error) return } // the responseData is XML !!!!!!!!!!!!!! let parser = XMLParser(data: responseData) parser.delegate = self parser.parse() } myTask.resume()
相应的XMLParserDelegate方法:
func parser(_ parser: XMLParser,didStartElement elementName: String,namespaceURI: String?,qualifiedName qName: String?,attributes attributeDict: [String : String] = [:]) { self.resultTrip = elementName // print(elementName) if (self.resultTrip == "TripResult") { self.resultTime = "" } } func parser(_ parser: XMLParser,foundCharacters string: String) { let data = string.trimmingCharacters(in: .whitespacesAndNewlines) if data.count != 0 { switch self.resultTrip { case "TiMetabledTime": self.resultTime = data default: break } } } func parser(_ parser: XMLParser,didEndElement elementName: String,qualifiedName qName: String?) { if self.resultTrip == "TripResult" { // HERE IS THE MISSING BIT: HOW DO YOU USE A CODABLE struct ??? var myTrip = TripResult(from: <#Decoder#>) myTrip.resultID = self.resultTrip } print(resultTime) }
结构:
struct TripResult : Codable { let resultId : String? let trip : Trip? enum CodingKeys: String,CodingKey { case resultId = "ResultId" case trip } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) resultId = try values.decodeIfPresent(String.self,forKey: .resultId) trip = try Trip(from: decoder) } }
我怎么必须使用’codable’结构?有没有关于如何使用Codable协议进行XML分析的好例子?
任何帮助赞赏!
虽然有很多第三方库可以解析XML,但XMLParsing library包含一个XMLDecoder和一个使用Apple自己的Codable协议的XMLEncoder,它基于Apple的JSONEncoder / JSONDecoder,其变化符合XML标准.
链接:https://github.com/ShawnMoore/XMLParsing
W3School的XML To Parse:
<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,则不必重构.
有关此库的完整示例列表,请参阅存储库中的Sample XML文件夹.
Apple的解码器和编码器之间存在一些差异,以适应XML标准.这些如下:
XMLDecoder和JSONDecoder之间的差异
> XMLDecoder.DateDecodingStrategy有一个名为keyFormatted的额外案例.这种情况采用一个闭包,为您提供CodingKey,由您提供所提供密钥的正确DateFormatter.这只是JSONDecoder的DateDecodingStrategy上的一个简便案例.
> XMLDecoder.DataDecodingStrategy有一个名为keyFormatted的额外案例.这种情况采用一个闭包,由您提供正确的数据或nil为提供的密钥.这只是JSONDecoder的DataDecodingStrategy上的一个简便案例.
>如果符合Codable协议的对象具有数组,并且正在解析的XML不包含数组元素,则XMLDecoder将为该属性分配一个空数组.这是因为XML标准表示如果XML不包含该属性,则可能意味着这些元素中没有任何元素.
XMLEncoder和JSONEncoder之间的差异
>包含一个名为StringEncodingStrategy的选项,这个枚举有两个选项,deferredToString和cdata. deferredToString选项是默认选项,将字符串编码为简单字符串.如果选择了cdata,则所有字符串都将编码为CData.> encode函数比JSONEncoder更多地接受两个参数.函数中的第一个附加参数是RootKey字符串,它将整个XML包装在名为该键的元素中.此参数是必需的.第二个参数是XMLHeader,它是一个可选参数,如果要在编码的xml中包含此信息,则可以采用版本,编码策略和独立状态.