You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将本地XML文件中的备忘录数据解析到SwiftUI视图中

解决方案

1. 定义备忘录数据模型

先创建一个适配SwiftUI列表的结构体,存储单个备忘录的属性:

struct Memorandum: Identifiable {
    let id = UUID() // SwiftUI列表所需的唯一标识
    let identification: String
    let text: String
    let time: String
}

2. 编写XML解析器类

实现一个可被SwiftUI观察的解析器,用系统XMLParser处理XML解析逻辑,自动收集所有备忘录数据:

import Foundation
import Combine

class XMLParserManager: ObservableObject {
    @Published var memorandums: [Memorandum] = []
    @Published var errorMessage: String?
    
    private var currentIdentification = ""
    private var currentText = ""
    private var currentTime = ""
    
    func parseXML(from fileName: String) {
        guard let filePath = Bundle.main.path(forResource: fileName, ofType: "xml") else {
            errorMessage = "找不到指定的XML文件"
            return
        }
        
        let fileURL = URL(fileURLWithPath: filePath)
        let parser = XMLParser(contentsOf: fileURL)
        parser?.delegate = self
        parser?.parse()
    }
}

extension XMLParserManager: XMLParserDelegate {
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        // 遇到<memorandum>节点时提取属性值
        if elementName == "memorandum" {
            currentIdentification = attributeDict["identification"] ?? ""
            currentText = attributeDict["text"] ?? ""
            currentTime = attributeDict["time"] ?? ""
        }
    }
    
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        // 结束<memorandum>节点时,将数据存入数组
        if elementName == "memorandum" {
            let memo = Memorandum(
                identification: currentIdentification,
                text: currentText,
                time: currentTime
            )
            memorandums.append(memo)
            
            // 重置临时变量
            currentIdentification = ""
            currentText = ""
            currentTime = ""
        }
    }
    
    func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
        errorMessage = "解析错误:\(parseError.localizedDescription)"
    }
}

3. SwiftUI视图实现

构建展示列表的视图,自动触发解析并展示结果,同时处理错误提示:

import SwiftUI

struct MemorandumListView: View {
    @StateObject private var parserManager = XMLParserManager()
    
    var body: some View {
        NavigationStack { // iOS 16+使用,iOS 15及以下替换为NavigationView
            List(parserManager.memorandums) { memo in
                Text("\(memo.identification) - \(memo.text) - \(memo.time)")
                    .padding(.vertical, 8)
            }
            .navigationTitle("备忘录列表")
            .onAppear {
                // 加载解析指定XML文件,可替换为其他文件名
                parserManager.parseXML(from: "test")
            }
            .alert(item: $parserManager.errorMessage) { message in
                Alert(title: Text("错误"), message: Text(message), dismissButton: .default(Text("确定")))
            }
        }
    }
}

// 让String适配Alert的Identifiable要求
extension String: Identifiable {
    public var id: String { self }
}

struct MemorandumListView_Previews: PreviewProvider {
    static var previews: some View {
        MemorandumListView()
    }
}

4. 灵活扩展说明

  • 解析多文件:只需重复调用parserManager.parseXML(from: "文件名"),若需保留多文件数据,可修改解析器去掉数组清空逻辑,或新增分组存储结构。
  • 适配XML结构变更:修改XMLParserDelegate中的元素名、属性名即可,无需改动视图层。
  • 大文件性能优化:将解析逻辑移至后台队列,避免阻塞UI,修改parseXML方法:
func parseXML(from fileName: String) {
    DispatchQueue.global(qos: .background).async {
        guard let filePath = Bundle.main.path(forResource: fileName, ofType: "xml") else {
            DispatchQueue.main.async {
                errorMessage = "找不到指定的XML文件"
            }
            return
        }
        
        let fileURL = URL(fileURLWithPath: filePath)
        let parser = XMLParser(contentsOf: fileURL)
        parser?.delegate = self
        let success = parser?.parse() ?? false
        
        DispatchQueue.main.async {
            if !success {
                errorMessage = "解析失败"
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者kostodian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:45:34