在 Swift (iOS/macOS) 中处理 XML:完整指南
XML(可扩展标记语言)仍然是数据交换、配置文件和 Web 服务中广泛使用的格式。在 Apple 生态系统中,Swift 处理 XML 既可以使用 Foundation 内置工具(XMLParser 类),也可以使用第三方库,例如 SwiftXML。在本文中,我们将通过 iOS 和 macOS 的代码示例详细讨论这两种方法。
1. Foundation 中的内置 XMLParser
XMLParser 是一个 SAX 解析器(顺序的、事件驱动的)。它不会将整个文档加载到内存中,而是在读取时逐步解析,并调用委托方法。这对于大型 XML 文件非常理想。
1.1. 基本设置和委托
创建一个实现 XMLParserDelegate 协议的类。必需的方法:
parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)— 在打开标签时调用。parser(_:foundCharacters:)— 获取元素的文本内容。parser(_:didEndElement:namespaceURI:qualifiedName:)— 在关闭标签时调用。
import Foundation
class XMLHandler: NSObject, XMLParserDelegate { var currentElement = "" var currentText = ""
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { currentElement = elementName currentText = "" if elementName == "book" { print("开始书籍: \\(attributeDict["id"] ?? "")") } }
func parser(_ parser: XMLParser, foundCharacters string: String) { currentText += string }
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { if elementName == "title" { print("标题: \\(currentText.trimmingCharacters(in: .whitespacesAndNewlines))") } }}
// 使用if let url = Bundle.main.url(forResource: "books", withExtension: "xml"), let parser = XMLParser(contentsOf: url) { let handler = XMLHandler() parser.delegate = handler parser.parse()}1.2. 错误处理和命名空间
实现 parser(_:parseErrorOccurred:) 方法来记录错误。要处理命名空间,请使用 namespaceURI 和 qualifiedName 参数。
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) { print("解析错误: \\(parseError.localizedDescription)")}2. 手动创建 XML 文档
在 Swift 中生成 XML 可以使用字符串或 Foundation 中的 XMLDocument 库(仅适用于 macOS)。在 iOS 上,您需要手动创建 XML。
2.1. 通过字符串生成 XML (iOS/macOS)
func createXMLString() -> String { var xml = "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>" xml += "<library>" xml += " <book id=\\"1\\">" xml += " <title>Swift Programming</title>" xml += " <author>Apple Inc.</author>" xml += " </book>" xml += "</library>" return xml}
let xmlString = createXMLString()print(xmlString)2.2. 使用 XMLDocument (仅 macOS)
import Foundation
let root = XMLElement(name: "library")let book = XMLElement(name: "book")book.addAttribute(XMLNode.attribute(withName: "id", stringValue: "1") as! XMLNode)
let title = XMLElement(name: "title", stringValue: "Swi