未调用 XMLParser 委托方法

XMLParser Delegate Methods not Called

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

这一切 运行 当我把每个 运行 都用 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)
    }
}

你需要一个强有力的参考

class ViewController: UIViewController{
   var parser:XMLParserHelper!
   override func viewDidLoad() {
     super.viewDidLoad()
     parser = XMLParserHelper()
     parser.runParser()
   }
}

要使 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.