Swift中如何同时使用多个XMLParser实例解析不同XML数据集
Swift多份XML数据集解析方案
核心问题定位
你遇到的回调不触发问题和第一份XMLParser占用完全无关,是代码写法错误导致:
- 第二份解析的
XMLParserDelegate协议方法全部定义在initializeSecondParser函数内部,属于局部嵌套函数,没有作为类的协议实现暴露给XMLParser,因此解析器无法触发回调。 - XMLParser每个实例都是独立的,支持同时/先后创建多个实例解析不同XML数据,不存在全局占用冲突。
现有代码修复方案
将SomeClassViewController中的代理方法移到类作用域,不要嵌套在函数内部,修正后代码如下:
class SomeClassViewController: UIViewController, XMLParserDelegate { var xmlParserSecondParser: XMLParser! var eName: String = String() override func viewDidLoad() { super.viewDidLoad() } func initializeSecondParser(){ guard let xmlData = HelperController.sharedInstance.XMLDataObjectSecond else { print("第二份XML数据为空") return } self.xmlParserSecondParser = XMLParser(data: xmlData) self.xmlParserSecondParser.delegate = self self.xmlParserSecondParser.parse() } // 代理方法移到类的作用域 func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { eName = elementName if elementName == "someName" { // 对应解析逻辑 } } func parser(_ parser: XMLParser, foundCharacters string: String) { let data = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased() if (!data.isEmpty) { // 对应解析逻辑 } } func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { eName = "" if elementName == "someName" { // 对应解析逻辑 } } // 可选:监听解析完成/错误 func parserDidEndDocument(_ parser: XMLParser) { print("第二份XML解析完成") } func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) { print("解析错误:\(parseError.localizedDescription)") } }
优化方案:封装独立解析工具
避免解析逻辑和ViewController耦合,支持任意多份XML同时解析,示例封装如下:
class CustomXMLParser: NSObject, XMLParserDelegate { private var parser: XMLParser? private var eName: String = "" // 解析完成回调 var parseCompletion: (([Any]?, Error?) -> Void)? // 自定义存储解析结果的属性 private var resultList = [Any]() init(data: Data) { super.init() parser = XMLParser(data: data) parser?.delegate = self } func startParse() { parser?.parse() } // 代理实现 func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { eName = elementName // 对应解析逻辑 } // 其余代理方法根据需求实现... func parserDidEndDocument(_ parser: XMLParser) { parseCompletion?(resultList, nil) } func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) { parseCompletion?(nil, parseError) } }
使用方式:
// 同时解析两份XML完全互不干扰 if let data1 = HelperController.sharedInstance.XMLDataObject { let parser1 = CustomXMLParser(data: data1) parser1.parseCompletion = { result, error in // 处理第一份解析结果 } parser1.startParse() } if let data2 = HelperController.sharedInstance.XMLDataObjectSecond { let parser2 = CustomXMLParser(data: data2) parser2.parseCompletion = { result, error in // 处理第二份解析结果 } parser2.startParse() }
时序控制说明
- 先后解析:可以在第一份解析的完成回调中触发第二份解析即可。
- 同时解析:直接创建多个
CustomXMLParser实例分别调用解析方法即可,实例之间完全独立不会冲突。
内容的提问来源于stack exchange,提问作者TommyF
相关产品推荐
相关产品推荐

