RPP
RPP

Reputation: 55

Parse the xml array and store the data into array or dictionary using swift

I need to parse the xml data using nsxmlparser.But i am facing issue getting the required data and storing it to array or dictionary using swift.I have implemented the the delegate function and able to find the element name like this

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
    }

however m not able to implement the same using swift.My xml looks like this

    <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>

Upvotes: 0

Views: 1976

Answers (1)

Patrick Lynch
Patrick Lynch

Reputation: 2782

That's a weird mix of Swift and Objective-C you posted, and it looks like you're trying to read the attributes of each <category>, but really you need to get the value of each child node of <category>. Try this:

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 )
}

Upvotes: 1

Related Questions