Swift解析XML主要用XMLParser配合Delegate,基于事件驱动、低内存;支持从URL、Data初始化,需实现didStartElement、foundCharacters、didEndElement三个回调,注意状态管理、空格处理及错误捕获。

Swift 解析 XML 主要用 XMLParser(iOS 8+ 替代了旧版 NSXMLParser)配合 XMLParserDelegate 协议实现。它基于事件驱动、内存占用低,适合解析中等规模的 XML,但不构建完整 DOM 树,需自己管理状态和数据结构。
XMLParser 初始化方式
支持三种常见初始化方式,按使用场景选择:
-
从本地文件 URL 初始化:适用于 bundle 内的 .xml 文件
let url = Bundle.main.url(forResource: "data", withExtension: "xml")!let parser = XMLParser(contentsOf: url) -
从 Data 初始化:适合网络请求返回的 XML 数据或字符串转 Data
let data = xmlString.data(using: .utf8)!let parser = XMLParser(data: data) -
从网络 URL 直接初始化(注意:iOS 15+ 已弃用,建议用 URLSession 先下载再解析)
if let parser = XMLParser(contentsOf: remoteURL) { ... }(仅限 HTTP/HTTPS 且无认证等限制场景)
关键 Delegate 方法作用与写法要点
必须实现 XMLParserDelegate,核心是三个回调方法,顺序固定:开始标签 → 内容字符 → 结束标签。别漏掉状态清理和空格处理。
-
didStartElement:进入节点时触发,获取节点名、命名空间、属性字典
常用操作:记录当前节点名(如currentElement = elementName),检查是否为目标节点(如if elementName == "user"),提取属性(attributes["id"]) -
foundCharacters:读取到文本内容时触发(可能被多次调用!)
务必用string.trimmingCharacters(in: .whitespacesAndNewlines)去除换行/空格;建议累积到临时变量(如currentValue += string),不要直接 print 或赋值 -
didEndElement:节点闭合时触发,此时
currentValue是该节点完整文本
根据elementName判断是否要保存数据(如if elementName == "name" { user.name = currentValue }),之后清空currentValue
处理同名子节点和嵌套结构
XML 中常有多个 或嵌套如 ,靠状态机管理:
- 用栈或层级计数跟踪嵌套深度(例如进入
address时设inAddress = true,退出时重置) - 遇到同名节点(如多个
)时,在didStartElement中新建模型对象,在didEndElement遇到父节点(如persons)再追加进数组 - 避免在
foundCharacters里直接存值——因为父子节点文本会连续触发,必须结合当前currentElement判断归属
错误处理与调试技巧
解析失败很常见,不能只看 parse() 返回值,要主动监听错误和生命周期:
- 实现
parser(_:, parseErrorOccurred:)捕获具体错误(如编码不对、标签未闭合) - 加上
parserDidStartDocument和parserDidEndDocument打印日志,确认是否真正走完全流程 - 调试时先用简单 XML(如单层几个标签)验证逻辑,再逐步加嵌套和属性
- 注意:XML 必须是 UTF-8 编码;含中文时确保文件保存为 UTF-8 无 BOM,否则
foundCharacters可能为空
基本上就这些。不用第三方库也能稳稳解析,关键是理清“事件流 + 状态变量”的配合逻辑。










