Swift中解析XML主要使用Foundation框架的XMLParser类和XMLParserDelegate协议,通过事件驱动方式处理中小型数据。首先创建XMLParser实例并设置代理,实现关键代理方法:didStartElement用于识别标签和属性,foundCharacters需拼接文本内容以应对分段调用,didEndElement在结束标签时保存数据,parserDidEndDocument用于完成回调。以解析RSS为例,可在item开始时初始化字典,逐字段收集内容,item结束时存入数组。注意元素名区分大小写、foundCharacters多次调用问题,并建议对大型文件流式处理。错误可通过parseErrorOccurred获取,确保解析稳定性。

Swift 中解析 XML 数据主要依赖 Foundation 框架提供的 XMLParser 类,配合 XMLParserDelegate 协议实现。虽然 Swift 本身没有内置的高级 XML 解析库(如 JSON 的 Codable),但通过原生 API 可以高效处理中小型 XML 数据。下面详细介绍如何使用 XMLParser 和其代理协议来解析 XML。
XMLParser 与 XMLParserDelegate 基本用法
XMLParser 是 Foundation 提供的 SAX(Simple API for XML)风格解析器,采用事件驱动方式逐行读取 XML 内容,适合内存受限场景。你需要实现 XMLParserDelegate 协议中的方法,在特定节点触发时接收回调。
基本步骤如下:
• 创建 XMLParser 实例,传入 Data 或字符串流• 设置 delegate 为当前类(需遵循 XMLParserDelegate)
• 调用 parse() 开始解析
• 在 delegate 方法中收集数据
示例代码结构:
class XMLHandler: NSObject, XMLParserDelegate {
var currentElement = ""
var currentValue = ""
var items = [[String: String]]()
func parse(xmlData: Data) {
let parser = XMLParser(data: xmlData)
parser.delegate = self
parser.parse()
}
}
关键 Delegate 方法详解
XMLParserDelegate 提供多个回调方法,用于响应 XML 解析过程中的不同阶段。以下是常用方法及其用途:
parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)
当遇到开始标签时调用,可用于识别当前元素名和读取属性。
func parser(_ parser: XMLParser,
didStartElement elementName: String,
namespaceURI: String?,
qualifiedName qName: String?,
attributes attributeDict: [String : String] = [:]) {
currentElement = elementName
currentValue = ""
// 处理标签属性,比如 -
if elementName == "item", let id = attributeDict["id"] {
print("Item ID: $id)")
}
}
parser(_:foundCharacters:)
解析到标签内文本内容时触发,注意此方法可能被多次调用(分段读取),需拼接字符串。
func parser(_ parser: XMLParser, foundCharacters string: String) {
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmed.isEmpty {
currentValue += trimmed
}
}
parser(_:didEndElement:namespaceURI:qualifiedName:)
结束标签时调用,通常在这里保存已完成的数据项。
func parser(_ parser: XMLParser,
didEndElement elementName: String,
namespaceURI: String?,
qualifiedName qName: String?) {
if elementName == "title" {
// 假设我们正在收集 item 下的字段
items.last?["title"] = currentValue
}
else if elementName == "item" {
// 完整 item 结束,可添加新字典
items.append([:])
}
}
parserDidEndDocument(_:)
整个文档解析完成后调用,适合收尾处理或通知完成。
func parserDidEndDocument(_ parser: XMLParser) {
print("XML 解析完成,共 $items.count) 条记录")
}
实际应用示例:解析 RSS 订阅
假设我们要解析一个简单的 RSS feed:
新闻标题 https://example.com
对应的解析逻辑:
var currentElement = ""
var currentItem: [String: String]?
var articles = [[String: String]]()
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attrDict: [String : String]) {
currentElement = elementName
if elementName == "item" {
currentItem = [:]
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
let content = string.trimmingCharacters(in: .whitespacesAndNewlines)
if !content.isEmpty {
currentItem?[currentElement, default: ""] += content
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "item", let item = currentItem {
articles.append(item)
currentItem = nil
}
}
注意事项与最佳实践
使用 XMLParser 时有几个关键点需要注意:
• foundCharacters 可能被多次调用,不要直接赋值,应使用 += 拼接• 元素名区分大小写,确保匹配正确(如 "Title" ≠ "title")
• 遇到嵌套结构时,可用栈管理层级状态
• 对大型文件建议流式处理,避免一次性加载全部内容
• 出错时可通过 parser(_:parseErrorOccurred:) 获取错误信息
错误处理示例:
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print("XML 解析出错: $parseError.localizedDescription)")
}
基本上就这些。XMLParser 虽不如 JSON 那样方便,但在处理标准 XML 格式(如 SOAP、RSS、配置文件)时依然可靠。只要合理组织 delegate 回调逻辑,就能稳定提取所需数据。










