Reputation: 153
I have the following XML structure which I want to parse:
<plist version="1.0">
<dict>
<key>
PALABRA
</key>
<array>
<string>
CATEGORY
</string>
<string>
WORD
</string>
</array>
</dict>
</plist>
I am using NSXMLParser in this way to parse the 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)
}
}
The value I get from the server for CATEGORY is the content of CATEGORY, but also the content of WORD, and the value for WORD is only WORD content. I know this is not the right way to parse the XML. The problem is that I don´t know how to get the CATEGORY and WORD elements, since both of them have the same ID ("String"). What would be the right way to get this information?
The server address is: http://www.serverbpw.com/cm/2016-1/hangman.php
Thanks in advance!
Upvotes: 0
Views: 2240
Reputation: 438297
If you're going to parse this yourself, the trick is that you have two occurrences of <string>
, and you have to differentiate them somehow. You could have your own counter to keep track of which one was which:
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)
}
}
But I agree with cezheng that this appears to by a NSDictionary
plist, and as such, you should just use NSDictionary(contentsOfFile)
or what have you. And if this is really a XML that you're building, I'd suggest a different format, e.g.:
<posts>
<post>
<category>
CATEGORY
</category>
<word>
WORD
</word>
</post>
</posts>
Then you could parse this far more easily, without the silliness of the counter
.
Upvotes: 2
Reputation: 564
This is a plist so you can just use NSDictionary(contentsOfFile:).
if let dict = NSDictionary(contentsOfFile: filePath) {
let array = dict["PALABRA"] as? [String]
let category = array?[0]
let word = array?[1]
}
if you don't have the data as a file, use this method
if let dict = try NSPropertyListSerialization.propertyListWithData(xmlData, options: .Immutable, format: nil) as? NSDictionary {
//......
}
Upvotes: 1