首页 > 解决方案 > 未调用 XMLParser 委托方法

问题描述

我正在尝试将 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)
    }
}

标签: iosswiftnsxmlparser

解决方案


为了使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)
    }
}

XMLParserjust 需要在运行时保持parse(),因此您无需声明xmlParserXMLParserHelper.


推荐阅读