如何在 swift 中同时使用多个 xmlparsers?

Posted

技术标签:

【中文标题】如何在 swift 中同时使用多个 xmlparsers?【英文标题】:How to use multiple xmlparsers in swift at the same time? 【发布时间】:2021-12-25 11:56:28 【问题描述】:

在斯威夫特。当我使用 xmlparser 为 ONE 实例呈现数据时,它可以正常工作,但是如果我尝试呈现两个不同的 xml 数据集,它就无法正常工作。据我了解,xmlparser 是同步的,所以这会为第二个 xmlparser 调用搞砸。那么如何同时(或依次)渲染两个不同数据集的 xml 数据呢?

这就是我渲染我的一个工作正常的数据集的方式。我包括 XMLParserDelegate:

var xmlParser: XMLParser!

self.xmlParser = XMLParser(data: HelperController.sharedInstance.XMLDataObject!)
self.xmlParser.delegate = self
self.xmlParser.parse()

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) 
    eName = elementName
    if elementName == "someName"  
        //do something
    


func parser(_ parser: XMLParser, foundCharacters string: String) 
    let data = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
    //var jalla = NSString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
    if (!data.isEmpty) 
        //do something 
    


func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) 
    eName = ""
    if elementName == "someName" 
      //do something
     

但我需要渲染另一个 XMLDataObject。我怎样才能做到这一点?如果我将第二个 xmlparsing 添加到一个新类并从那里初始化它,它将不会输入 didStartElement(因为我猜第一个 xmlParser 目前很忙)。

编辑:

我尝试了很多不同的方法来添加第二个解析器。我现在尝试的方法是我在单独的类中有第二个解析器,如下所示:

class SomeClassViewController: UIViewController, XMLParserDelegate 

var xmlParserSecondParser: XMLParser!
var eName: String = String()

override func viewDidLoad() 
    super.viewDidLoad()

    // Do any additional setup after loading the view.


func initializeSecondParser()
    self.xmlParserSecondParser = XMLParser(data: 
                   HelperController.sharedInstance.XMLDataObjectSecond!)
    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"  
           //do something
         
    

    func parser(_ parser: XMLParser, foundCharacters string: String) 
       let data = string.trimmingCharacters(in: 
       CharacterSet.whitespacesAndNewlines).uppercased()
         if (!data.isEmpty) 
          //do something 
         
    

   func parser(_ parser: XMLParser, didEndElement elementName: String, 
       namespaceURI: String?, qualifiedName qName: String?) 
          eName = ""
          if elementName == "someName" 
            //do something
           
   


当我运行第一个解析器时,我还调用了 initializeSecondParser() 但这不起作用,因为从不调用 didStartElement。

let someClassViewController = SomeClassViewController();
someClassViewController.initializeSecondParser();

我也尝试过使第二次调用异步但没有运气:

DispatchQueue.main.async 
  let someClassViewController = SomeClassViewController();
  someClassViewController.initializeSecondParser();

【问题讨论】:

不清楚。你能展示你如何创建你的第二个解析器吗?你能澄清一下类/委托方法的哪一部分吗? @Larme 我在下面添加了您的问题的答案 编辑你的问题,而不是作为答案,因为它没有回答你的问题...... 是的,我会这样做,但昨天编辑按钮不可见。现在它是可见的,我已将文本移至原始帖子 【参考方案1】:

您需要正确分离解析器:

struct CustomParser: XMLParserDelegate 
    let xmlParser: XMLParser
    let ename: String = ""
    init(with data: Data) 
        xmlParser = XMLParser(data: data)
        xmlParser.delegate = self
    
    
    // Here its returning the value you want
    var parsedResponse: ParsedResponse?
    func parse() -> ParsedResponse? 
        xmlParser.parse()
        return parsedResponse
    
    // ParserDelegates
    func parser(_ parser: XMLParser, foundCharacters string: String) 
        ...
    
    func parser(_ parser: XMLParser, didEndElement elementName: String, 
       namespaceURI: String?, qualifiedName qName: String?) 
        ...
    
    ...




let parser1 = CustomParser(with: HelperController.sharedInstance.XMLDataObjectFirst!)
let parsed1 = parser1.parse()

let parser2 = CustomParser(with: HelperController.sharedInstance.XMLDataObjectSecond!)
let parsed2 = parser2.parse()

这是我推荐的方式,因为您正确地将解析与 UIViewController 分开。你不会有大的UIViewController 来进行 XML 解析,还有更多......

您仍然可以使用 2 解析器,但是您展示的内容很少,这可能会更难,即检查委托方法中的 parser 并采取相应措施,但这会增加复杂性并容易出错(忘记某处某事,然后打破一切):

var firstParser: XMLParser!
var firstEName: String = String()
var secondParser: XMLParser!
var secondEName: String = String()

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) 

    if parser == firstParser 
        firstEName = elementName
        if elementName == "someName"  
           //do something
        
     else if parser == secondParser 
        secondEName = elementName
        if elementName == "someName"  
           //do something
        
     else 
        //It's another parser, what to do?
    

然后检查每个委托方法。因此,如果您忘记在其中一种方法中进行检查,您可能会得到奇怪的结果...

【讨论】:

非常感谢!它可以检查委托方法中使用了哪个解析器。

以上是关于如何在 swift 中同时使用多个 xmlparsers?的主要内容,如果未能解决你的问题,请参考以下文章

一个 UIView Swift 中的多个 TableViews - 如何同时显示

如何限制同时调用函数的多个定时器函数? Swift 3+

如何在 IOS Swift 中使用 SQLite 使用 FMDB 处理多个线程

为啥我不能使用 Swift 4 加载 Collada 文件?

如何在 Swift 3 中多点触摸 UICollectionViewCell

Swift:多个函数同时工作