Alamofire XML 请求 PropertyList
Alamofire XML request to PropertyList
我正在尝试使用示例 https://www.w3schools.com/xml/note.xml 中的 Codable 解析 XML 数据。
我的结构是
struct Note: Codable {
var to: String?
var from: String?
var heading: String?
var body: String?
}
但是,如果我提出以下请求,我会得到错误 responseSerializationFailed : ResponseSerializationFailureReason
"PropertyList could not be serialized because of error:\nThe data couldn’t be read because it isn’t in the correct format."
let url = URL(string: "https://www.w3schools.com/xml/note.xml")
Alamofire.request(url!, method: .get, encoding: PropertyListEncoding.default).responsePropertyList { (response) in
guard response.error == nil else {
print(response.error!)
exp.fulfill()
return
}
print(response)
if let data = response.data {
print(data)
let decoder = PropertyListDecoder()
let note = try! decoder.decode(Note.self, from: data)
print(note)
}
}
你是如何在 Alamofire 中使用 responsePropertyList 的?
PropertyList 文件虽然是 XML 格式,但它们需要遵循 Apple 的 PropertyList DTD:http://www.apple.com/DTDs/PropertyList-1.0.dtd
如果您想将常规 XML 文件(不遵循 PropertyList DTD)映射到模型对象中,并且您不介意使用外部库,您可以尝试 XMLMapper。
您为此 XML 建模应该如下所示:
class Note: XMLMappable {
var nodeName: String!
var to: String?
var from: String?
var heading: String?
var body: String?
required init(map: XMLMap) { }
func mapping(map: XMLMap) {
to <- map["to"]
from <- map["from"]
heading <- map["heading"]
body <- map["body"]
}
}
您可以使用 XMLMapper
:
从字符串映射它
let note = XMLMapper<Note>().map(XMLString: xmlString)
或者如果你安装了 Requests
子规范你可以使用 responseXMLObject(queue:keyPath:mapToObject:completionHandler:)
功能,如:
let url = URL(string: "https://www.w3schools.com/xml/note.xml")
Alamofire.request(url!, method: .get, encoding: XMLEncoding.default).responseXMLObject { (response: DataResponse<Note>) in
let note = response.result.value
print(note?.from ?? "nil")
}
希望对您有所帮助。
目前,Apple 的 Codable 协议无法解码 XML。虽然 Plist 是 XML,但 XML 不一定是 Plist,除非它遵循某种格式。
虽然有很多第三方库,但我建议您看看 XMLParsing library。这个库包含一个 XMLDecoder 和一个 XMLEncoder 使用 Apple 自己的 Codable 协议,并基于 Apple 的 JSONEncoder/JSONDecoder 进行更改以适应 XML 标准。
Link: 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 符合 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,你就不必重构。
有关此库示例的完整列表,请参阅存储库中的示例 XML 文件夹。
Apple 的解码器和编码器之间存在一些差异以符合 XML 标准。这些如下:
XML解码器和 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.
中包含这些信息
我正在尝试使用示例 https://www.w3schools.com/xml/note.xml 中的 Codable 解析 XML 数据。
我的结构是
struct Note: Codable {
var to: String?
var from: String?
var heading: String?
var body: String?
}
但是,如果我提出以下请求,我会得到错误 responseSerializationFailed : ResponseSerializationFailureReason
"PropertyList could not be serialized because of error:\nThe data couldn’t be read because it isn’t in the correct format."
let url = URL(string: "https://www.w3schools.com/xml/note.xml")
Alamofire.request(url!, method: .get, encoding: PropertyListEncoding.default).responsePropertyList { (response) in
guard response.error == nil else {
print(response.error!)
exp.fulfill()
return
}
print(response)
if let data = response.data {
print(data)
let decoder = PropertyListDecoder()
let note = try! decoder.decode(Note.self, from: data)
print(note)
}
}
你是如何在 Alamofire 中使用 responsePropertyList 的?
PropertyList 文件虽然是 XML 格式,但它们需要遵循 Apple 的 PropertyList DTD:http://www.apple.com/DTDs/PropertyList-1.0.dtd
如果您想将常规 XML 文件(不遵循 PropertyList DTD)映射到模型对象中,并且您不介意使用外部库,您可以尝试 XMLMapper。
您为此 XML 建模应该如下所示:
class Note: XMLMappable {
var nodeName: String!
var to: String?
var from: String?
var heading: String?
var body: String?
required init(map: XMLMap) { }
func mapping(map: XMLMap) {
to <- map["to"]
from <- map["from"]
heading <- map["heading"]
body <- map["body"]
}
}
您可以使用 XMLMapper
:
let note = XMLMapper<Note>().map(XMLString: xmlString)
或者如果你安装了 Requests
子规范你可以使用 responseXMLObject(queue:keyPath:mapToObject:completionHandler:)
功能,如:
let url = URL(string: "https://www.w3schools.com/xml/note.xml")
Alamofire.request(url!, method: .get, encoding: XMLEncoding.default).responseXMLObject { (response: DataResponse<Note>) in
let note = response.result.value
print(note?.from ?? "nil")
}
希望对您有所帮助。
目前,Apple 的 Codable 协议无法解码 XML。虽然 Plist 是 XML,但 XML 不一定是 Plist,除非它遵循某种格式。
虽然有很多第三方库,但我建议您看看 XMLParsing library。这个库包含一个 XMLDecoder 和一个 XMLEncoder 使用 Apple 自己的 Codable 协议,并基于 Apple 的 JSONEncoder/JSONDecoder 进行更改以适应 XML 标准。
Link: 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 符合 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,你就不必重构。
有关此库示例的完整列表,请参阅存储库中的示例 XML 文件夹。
Apple 的解码器和编码器之间存在一些差异以符合 XML 标准。这些如下:
XML解码器和 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.