解析xml数组并使用swift将数据存储到数组或字典中

时间:2015-07-29 08:00:35

标签: arrays xml swift nsxmlparser

我需要使用nsxmlparser解析xml数据。但我面临着使用swift获取所需数据并将其存储到数组或字典的问题。我已经实现了委托函数并且能够找到像这样的元素名称

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject])
{
    println(elementName)
    if(elementName == "subCategories")
    {
        categoryName: String = [attributeDict valueForKey:"category"];
        id = [attributeDict valueForKey:"id"];
        name = [attributeDict valueForKey:"name"];
        // Now You can store these in your preferable data models - data objects/array/dictionary
    }

然而我无法使用swift实现相同的。我的xml看起来像这样

    <category>
  <id>cat00000</id>
  <name>Best Buy</name>
  <active>true</active>
  <path>
     <category>
        <id>cat00000</id>
        <name>Best Buy</name>
     </category>
  </path>
  <subCategories>
     <category>
        <id>abcat0100000</id>
        <name>TV &amp; Home Theater</name>
     </category>
     <category>
        <id>abcat0200000</id>
        <name>Audio</name>
     </category>
     <category>
        <id>abcat0300000</id>
        <name>Car Electronics &amp; GPS</name>
     </category>

1 个答案:

答案 0 :(得分:1)

你发布了Swift和Objective-C的奇怪组合,看起来你正在尝试阅读每个<category>的属性,但实际上你需要得到的价值<category>的每个子节点。试试这个:

class CategoryParser: NSObject, NSXMLParserDelegate {

    var subcategories = [[String : String]]()
    var currentSubcategory: [String : String]?
    var currentElementName: String?

    var completion: (([[String : String]]) -> ())?

    func parseXML( string: String, completion: (([[String : String]]) -> ())? ) {
        guard let data = string.dataUsingEncoding( NSUTF8StringEncoding ) else {
            fatalError( "Base XML data" )
        }
        self.completion = completion
        let parser = NSXMLParser(data: data )
        parser.delegate = self
        parser.parse()
    }

    func parserDidEndDocument(parser: NSXMLParser) {
        self.completion?( self.subcategories )
    }

    func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
        print( "Parse error: \(parseError)" )
    }

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

        if let elementName = self.currentElementName {
            if [ "id", "name" ].contains( elementName ) {
                self.currentSubcategory?[ elementName ] = string
            }
        }
    }

    func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        if elementName == "category", let subcategory = self.currentSubcategory {
            self.subcategories.append( subcategory )
            self.currentSubcategory = nil
        }
    }

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

        if elementName == "category" {
            self.currentSubcategory = [String : String]()
        }
        else {
            self.currentElementName = elementName
        }
    }
}



let categoryParser = CategoryParser()
let xmlString = "<subCategories><category><id>someId</id><name>someName</name></category></subCategories>"
categoryParser.parseXML( xmlString ) { (categories) in
    print( categories )
}