NSXMLParser parse()只能运行一次

时间:2016-05-18 15:58:21

标签: ios xml swift parsing

我正在读取XML feed以填充tableView,我正在使用NSXMLParser来解析XML。第一次解析数据时,一切正常,我得到的表格就像我期望的那样填充。然后我设置一个计时器来定期更新服务器中的数据。当计时器触发时,我使用完全相同的方法再次解析相同的XML提要,然后它总是失败:parser.parse()返回false,但没有报告错误。我可以获得它失败的行号和列,但数据通常与它第一次解析XML时没有什么不同(并且它在那时工作)。

我在TableViewController中声明了解析器:

var parser = NSXMLParser()

在ViewDidLoad中我配置它:

    let url: String = "http://www.deltatao.com/clanlord/status/cldata.xml"

    let urlToSend: NSURL = NSURL(string: url)!

    parser = NSXMLParser(contentsOfURL: urlToSend)!
    parser.delegate = self

在ViewWillAppear中,我调用它并设置计时器:

    parseClanlordInformation()
    // this will remove the previous timer
    timer?.invalidate()
    // now start a timer to regularly update the data from the server
    startTimer()

这是调用parse()的函数:

func parseClanlordInformation() {

    // reset players list
    players.removeAll()
    // Stop the previous parsing operation in case it was still running
    parser.abortParsing()
    // rebuild the list from scratch
    let success: Bool = parser.parse()

    if !success {
        let error = parser.parserError
        let line = parser.lineNumber
        let col = parser.columnNumber
        print("XML parsing failed at \(line):\(col): \(error?.localizedDescription)")
        print(players.count)
    }

    if parser.parserError != nil {
        print("Error: parse failure!")
        print(parser.parserError)
    }

    myTableView.reloadData()


}

定时器调用相同的功能:

func startTimer() {
    timer = NSTimer.scheduledTimerWithTimeInterval(updateInterval, target: self, selector: #selector(TableViewController.parseClanlordInformation), userInfo: nil, repeats: true)
}

XML Parser代理的设置如下:

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

    currentElement = elementName
    if elementName=="exile" || elementName=="race" || elementName=="name" || elementName=="sex" || elementName=="profession" || elementName=="clan"  {
        if elementName == "exile" {
            foundNewPlayer = true
            currentPlayer.reset()
        }
        passData = true
    }
}

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {

    currentElement = ""
    if elementName=="exile" || elementName=="race" || elementName=="name" || elementName=="cost" || elementName=="description" {
        if elementName == "exile" {
            foundNewPlayer=false
            players.append(currentPlayer)

        }
        passData=false
    }
}

func parser(parser: NSXMLParser, foundCharacters string: String) {

    if foundNewPlayer {
        switch currentElement {
            case "name":
                currentPlayer.name = string
            case "race":
                var race: String
                if string == "of the People" {
                    race = "Fen'neko"
                } else {
                    race = String(string.characters.dropFirst(2))
                }
                currentPlayer.race = race
            case "sex":
                currentPlayer.genre = string
            case "profession":
                let prof = String(string.characters.dropFirst(2))
                currentPlayer.profession = prof
            case "clan":
                currentPlayer.clan = string
        default: break

        }
    }

 }

func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
    print(parseError.description)
    NSLog("failure error: %@", parseError)
}

当我运行应用程序时,表正常填充数据,然后当第一次更新触发时,parser.parse()在第80行,第1列或其附近返回false。

为什么它只能运作一次?是否有一些我应该做的重置,我忘了?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我很确定NSXMLParser的给定实例只能使用一次。每次要再次解析时都创建一个新实例。

func parseClanlordInformation() {
    // reset players list
    players.removeAll()
    // Stop the previous parsing operation in case it was still running
    parser.abortParsing()

    // Setup new parser
    let url: String = "http://www.deltatao.com/clanlord/status/cldata.xml"
    let urlToSend: NSURL = NSURL(string: url)!

    parser = NSXMLParser(contentsOfURL: urlToSend)!
    parser.delegate = self

    // rebuild the list from scratch
    let success: Bool = parser.parse()

    if !success {
        let error = parser.parserError
        let line = parser.lineNumber
        let col = parser.columnNumber
        print("XML parsing failed at \(line):\(col): \(error?.localizedDescription)")
        print(players.count)
    }

    if parser.parserError != nil {
        print("Error: parse failure!")
        print(parser.parserError)
    }

    myTableView.reloadData()
}

这也意味着您可以删除viewDidLoad中的解析器设置。