在Swift 4中解析XML

瑞奇

我是Swift的XML解析的新手,我在Swift的URL中解析XML的过程中发现了这段代码,但是EXC_BAD_INSTRUCTION在尝试运行该代码时出现错误。错误的描述为:fatal error: unexpectedly found nil while unwrapping an Optional value

这是我的简单XML文件:

<xml>
    <book>
        <title>Book Title</title>
        <author>Book Author</author>
    </book>
</xml>

以下代码创建一个XMLParser对象并解析位于我的文档中的XML文件。

// get xml file path from Documents and parse

let filePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last?.appendingPathComponent("example.xml")

let parser = XMLParser(contentsOf: filePath!)
parser?.delegate = self

if (parser?.parse())! {
    print(self.results)
}

在这里,我实现这些XMLParserDelegate方法并定义我的字典:

// a few constants that identify what element names we're looking for inside the XML

let recordKey = "book"
let dictionaryKeys = ["title","author"]

// a few variables to hold the results as we parse the XML

var results: [[String: String]]!          // the whole array of dictionaries
var currentDictionary: [String: String]!  // the current dictionary
var currentValue: String?                 // the current value for one of the keys in the dictionary

// start element
//
// - If we're starting a "record" create the dictionary that will hold the results
// - If we're starting one of our dictionary keys, initialize `currentValue` (otherwise leave `nil`)


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

    if elementName == recordKey {

        currentDictionary = [String : String]()

    } else if dictionaryKeys.contains(elementName) {

        currentValue = String()

    }
}

// found characters
//
// - If this is an element we care about, append those characters.
// - If `currentValue` still `nil`, then do nothing.

func parser(_ parser: XMLParser, foundCharacters string: String) {

    currentValue? += string

}

// end element
//
// - If we're at the end of the whole dictionary, then save that dictionary in our array
// - If we're at the end of an element that belongs in the dictionary, then save that value in the dictionary


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

    if elementName == recordKey {

        results.append(currentDictionary)
        currentDictionary = nil

    } else if dictionaryKeys.contains(elementName) {

        currentDictionary[elementName] = currentValue
        currentValue = nil

    }
}

// Just in case, if there's an error, report it. (We don't want to fly blind here.)

func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {

    print(parseError)

    currentValue = nil
    currentDictionary = nil
    results = nil

}

将_附加到字典后,在didEndElement方法上发现错误currentDictionaryresults

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

    if elementName == recordKey {

        results.append(currentDictionary)    // Line with Error
        currentDictionary = nil

    } else if dictionaryKeys.contains(elementName) {

        currentDictionary[elementName] = currentValue
        currentValue = nil

    }
}

请帮我解决这个问题。我正在使用Swift中从URL解析XML提供的完全相同的代码,它们似乎没有任何问题。我做错什么了吗?

rmaddy

您的代码从未真正初始化过,results因此,第一次尝试使用它时,您将试图强制展开一个nil可选值。那很糟。并且没有理由将其声明为隐式展开的可选。

您需要更改:

var results: [[String: String]]!

至:

var results = [[String: String]]()

您还需要删除以下行:

results = nil

从你的parser(_:parseErrorOccurred:)方法。

如果您希望自己results是可选的,则可以对代码进行以下更改:

将声明更改results为:

var results: [[String: String]]? = [[String: String]]()

更改:

results.append(currentDictionary)

至:

results?.append(currentDictionary)

然后您将results = nil线路parser(_:parseErrorOccurred:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章