未调用XMLParser委托方法

时间:2018-11-10 12:42:00

标签: ios swift nsxmlparser

我正在尝试将XML解析器抽象到自定义类中,以便从VC运行它。它可以完美编译,并且我的错误处理程序显示成功。但是,实际的委托方法被跳过了。没有数据被解析。

当我每次都运行VC时,一切运行良好,但是我现在尝试摆脱意大利面条式的代码。

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let parser = XMLParserHelper()
        //try create file for persistent data
        //CreatePlist.createPlist()
        parser.runParser()
    }
}

class XMLParserHelper:  NSObject, XMLParserDelegate {
    //list type variables to hold XML values (update list base on XML structure):
    static var station: String = ""
    static var latitude: String = ""
    static var longitude: String = ""
    private static var code: String = ""
    private static var id: String = ""

    //reusable method type veriales (do not touch)
    static var strXMLData:String = ""
    static var currentElement:String = ""
    static var passData:Bool=false
    static var passName:Bool=false
    static var xmlParser = XMLParser()

    //parser methods
    func runParser(){
        let xmlPath = Bundle.main.url(forResource: "station", withExtension: "xml")
        let xmlParser = XMLParser(contentsOf: (xmlPath)!)
        xmlParser?.delegate = self
        let success:Bool = xmlParser!.parse()
        xmlParser?.parse()
        if success {
            print("parse success!")
            print(XMLParserHelper.currentElement)
        } else {
            print("parse failure!")
        }
    }

    private static func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
        XMLParserHelper.currentElement=elementName;
        if (elementName=="StationDesc" || elementName=="StationLatitude" || elementName=="StationLongitude" || elementName=="StationCode" || elementName=="StationId" ) {
            if (elementName=="StationDesc") {
                XMLParserHelper.passName=true;
            }
            XMLParserHelper.passData=true;
        }
    }

    private static func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        XMLParserHelper.currentElement="";
        if (elementName=="StationDesc" || elementName=="StationLatitude" || elementName=="StationLongitude" || elementName=="StationCode" || elementName=="StationId" ) {
            if(elementName=="StationDesc") {
                XMLParserHelper.passName=false;
            }
            XMLParserHelper.passData=false;
        }
    }

    private static func parser(_ parser: XMLParser, foundCharacters string: String) {
        if (XMLParserHelper.passName) {
            XMLParserHelper.strXMLData=XMLParserHelper.strXMLData+"\n\n"+string
        }

        if (XMLParserHelper.passData) {
            //ready content for codable struct
            switch XMLParserHelper.currentElement {
            case "StationDesc":
                XMLParserHelper.station = string
            case "StationLatitude":
                XMLParserHelper.latitude = string
            case "StationLongitude":
                XMLParserHelper.longitude = string
            case "StationCode":
                XMLParserHelper.code = string
            case "StationId":
                XMLParserHelper.id = string
                print(string)

            default:
                XMLParserHelper.id = string
            }
        }
    }

    func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
        print("failure error: ", parseError)
    }
}

2 个答案:

答案 0 :(得分:2)

要使XMLParserDelegate方法起作用,所有方法都必须是非静态,非私有方法。

因此,所有属性也应该是非静态的。

class XMLParserHelper: NSObject, XMLParserDelegate {

    //list type variables to hold XML values (update list base on XML structure):
    var station: String = ""
    var latitude: String = ""
    var longitude: String = ""
    private var code: String = ""
    private var id: String = ""

    //reusable method type veriales (do not touch)
    var strXMLData: String = ""
    var currentElement: String = ""
    var passData: Bool = false
    var passName: Bool = false

    //parser methods
    func runParser() {
        let xmlURL = Bundle.main.url(forResource: "station", withExtension: "xml")!
        let xmlParser = XMLParser(contentsOf: xmlURL)!
        xmlParser.delegate = self
        let success = xmlParser.parse()
        if success {
            print("parse success!")
            print(currentElement)
        } else {
            print("parse failure!")
        }
    }

    //MARK: XMLParserDelegate methods

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
        currentElement = elementName
        if elementName == "StationDesc"
        || elementName == "StationLatitude"
        || elementName == "StationLongitude"
        || elementName == "StationCode"
        || elementName == "StationId"
        {
            if elementName == "StationDesc" {
                passName = true
            }
            passData = true
        }
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        currentElement = ""
        if elementName == "StationDesc"
        || elementName == "StationLatitude"
        || elementName == "StationLongitude"
        || elementName == "StationCode"
        || elementName == "StationId"
        {
            if elementName == "StationDesc" {
                passName = false
            }
            passData = false
        }
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        if passName {
            strXMLData = strXMLData+"\n\n"+string
        }

        if passData {
            //ready content for codable struct
            switch currentElement {
            case "StationDesc":
                station = string
            case "StationLatitude":
                latitude = string
            case "StationLongitude":
                longitude = string
            case "StationCode":
                code = string
            case "StationId":
                id = string
                print(string)

            default:
                id = string
            }
        }
    }

    func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
        print("failure error: ", parseError)
    }
}

XMLParser仅在运行parse()时保持,因此您无需将xmlParser声明为XMLParserHelper的属性。

答案 1 :(得分:0)

您需要强大的参考资料

>>> price_report()
price_report
Celerio   500,000
i10       350,000
Amaze     800,000
Figo      550,000
End of price_report 


>>> sales_report()
sales_report
Celerio     5,000
i10         3,000
Amaze       1,000
Figo          800
End of sales_report