【问题标题】:Parsing XML in Swift with NSXMLParser使用 NSXMLParser 在 Swift 中解析 XML
【发布时间】:2016-02-10 16:08:17
【问题描述】:

我有以下要解析的 XML 结构:

<plist version="1.0">
        <dict>
            <key>
                PALABRA
            </key>
            <array>
                <string>
                    CATEGORY
                </string>
                <string>
                    WORD
                </string>
            </array>
        </dict>
</plist> 

我正在使用 NSXMLParser 以这种方式解析 XML:

var posts = NSMutableArray()
var parser = NSXMLParser()
var elements = NSMutableDictionary()
var element = NSString()
var CATEGORY = NSMutableString()
var WORD = NSMutableString()

func parseXML() {
        posts = []
        parser = NSXMLParser(contentsOfURL:(NSURL(string:"http://www.serverbpw.com/cm/2016-1/hangman.php"))!)!
        parser.delegate = self
        parser.parse()         
}

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

    element = elementName
    if (elementName as NSString).isEqualToString("array") {
        elements = NSMutableDictionary()
        elements = [:]
        categoria = NSMutableString()
        categoria = ""
    }

    if (elementName as NSString).isEqualToString("string") {
        palabra = NSMutableString()
        palabra = ""
    }
}

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

    if element.isEqualToString("string") {
        categoria.appendString(string)
    }

    if element.isEqualToString("string") {
        palabra.appendString(string)
    }
}

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if (elementName as NSString).isEqualToString("array") {
        if !categoria.isEqual(nil) {
            elements.setObject(categoria, forKey: "CATEGORIA")
        }
        if !palabra.isEqual(nil) {
            elements.setObject(palabra, forKey: "PALABRA")
        }            
        posts.addObject(elements)
    }
}

我从服务器获取的CATEGORY的值是CATEGORY的内容,也是WORD的内容,而WORD的值只是WORD的内容。 我知道这不是解析 XML 的正确方法。问题是我不知道如何获取 CATEGORY 和 WORD 元素,因为它们都具有相同的 ID(“字符串”)。获取此信息的正确方法是什么?

服务器地址为:http://www.serverbpw.com/cm/2016-1/hangman.php

提前致谢!

【问题讨论】:

  • 顺便说一句,我不鼓励将NSXMLParser(contentsOfURL) 与远程URL 一起使用。这会导致同步网络调用并阻塞主线程。最好异步检索数据,然后使用NSXMLParser引用本地文件或异步下载数据的NSData。

标签: ios xml swift parsing nsxmlparser


【解决方案1】:

如果你要自己解析这个,诀窍是你有两次出现&lt;string&gt;,你必须以某种方式区分它们。您可以拥有自己的计数器来跟踪哪个是哪个:

var posts: [[String: String]]!
var element: String!
var categoria: String?
var palabra: String?
var stringValue: String?
var counter: Int!

func parseXML(url: NSURL) {
    posts = [[:]]
    let parser = NSXMLParser(contentsOfURL: url)!
    parser.delegate = self
    parser.parse()
}

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
    element = elementName
    if elementName == "array" {
        categoria = nil
        palabra = nil
        counter = 0
    }
}

func parser(parser: NSXMLParser, foundCharacters string: String) {
    if element == "string" {
        if stringValue == nil {
            stringValue = string
        } else {
            stringValue! += string
        }
    }
}

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "string" {
        stringValue = stringValue?.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
        if counter == 0 {
            categoria = stringValue
        } else if counter == 1 {
            palabra = stringValue
        }
        stringValue = nil
        counter!++
    }

    if elementName == "array" {
        var element = [String: String]()
        if categoria != nil {
            element["CATEGORIA"] = categoria
        }
        if palabra != nil {
            element["PALABRA"] = palabra
        }            
        posts.append(element)
    }
}

但我同意cezheng 的观点,这似乎是NSDictionary plist,因此,你应该只使用NSDictionary(contentsOfFile) 或者你有什么。如果这确实是您正在构建的 XML,我建议使用不同的格式,例如:

<posts>
    <post>
        <category>
            CATEGORY
        </category>
        <word>
            WORD
        </word>
    </post>
</posts> 

然后你可以更容易地解析这个,而不会像 counter 那样愚蠢。

【讨论】:

  • 问题是XML不是我的,所以我不能修改它的结构。您的解决方案效果很好,它给了我我需要的东西。非常感谢!
【解决方案2】:

这是一个 plist,因此您可以使用 NSDictionary(contentsOfFile:)。

if let dict = NSDictionary(contentsOfFile: filePath) {
  let array = dict["PALABRA"] as? [String]
  let category = array?[0]
  let word = array?[1]
}

如果你没有数据作为文件,使用这个方法

if let dict = try NSPropertyListSerialization.propertyListWithData(xmlData, options: .Immutable, format: nil) as? NSDictionary {
    //......
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 2012-02-07
    • 1970-01-01
    • 2012-02-13
    • 2012-09-02
    相关资源
    最近更新 更多