在Swift开发中,如果服务端接口返回的是XML格式而不是常见的JSON,我们可以利用系统自带的XMLParser来完成解析。它采用SAX方式,边读边解析,适合处理较大的XML数据。下面通过一个完整示例说明如何从网络请求到XML解析的全过程。

发起网络请求获取XML数据
使用URLSession发起请求,拿到响应Data后交给解析器处理:
import Foundation
func fetchXML(from urlString: String, completion: @escaping (Data?) -> Void) {
guard let url = URL(string: urlString) else {
completion(nil)
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("请求失败: (error.localizedDescription)")
completion(nil)
return
}
completion(data)
}
task.resume()
}
实现XMLParserDelegate解析数据
创建一个解析类,遵守XMLParserDelegate协议,在代理方法中记录当前节点与内容:
class BookXMLParser: NSObject, XMLParserDelegate {
private var currentElement: String = ""
private var currentValue: String = ""
private var books: [String] = []
private var currentBook: [String: String] = [:]
func parse(data: Data) {
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
}
func parser(_ parser: XMLParser, didStartElement elementName: String,
namespaceURI: String?, qualifiedName qName: String?,
attributes attributeDict: [String : String] = [:]) {
currentElement = elementName
if elementName == "book" {
currentBook = [:]
}
currentValue = ""
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
currentValue += string.trimmingCharacters(in: .whitespacesAndNewlines)
}
func parser(_ parser: XMLParser, didEndElement elementName: String,
namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "title" {
currentBook["title"] = currentValue
} else if elementName == "author" {
currentBook["author"] = currentValue
} else if elementName == "book" {
books.append("(currentBook["title"] ?? "") by (currentBook["author"] ?? "")")
}
}
func getBooks() -> [String] {
return books
}
}
组合请求与解析
将网络请求和解析类组合起来,即可拿到结构化结果:
let xmlURL = "https://ipipp.com/books.xml"
fetchXML(from: xmlURL) { data in
guard let data = data else { return }
let parser = BookXMLParser()
parser.parse(data: data)
let result = parser.getBooks()
print(result)
}
注意事项
- XMLParser是异步事件解析,不要在代理方法里做繁重操作。
- 如果XML含有命名空间,需关注namespaceURI参数。
- 标签内的特殊字符如<和>会被自动处理,无需手动转义。
通过上述方式,Swift就能稳定解析网络请求返回的XML,并转换为业务需要的模型或字符串列表。