XML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class XMLToDict: NSObject { | |
public static let kText = "XMLToDictTextKey" | |
public static let kAttributes = "_XMLAttributes" | |
private var stack = [NSMutableDictionary]() | |
private var textBeingProcessed = "" | |
} | |
public extension XMLToDict { | |
static func makeDict(data: Data) -> [String:Any]? { | |
let parser = XMLToDict() | |
return parser.dictFrom(data: data) | |
} | |
} | |
public extension XMLToDict { | |
func dictFrom(data: Data) -> [String : Any]? { | |
stack = [NSMutableDictionary]() | |
textBeingProcessed = "" | |
stack.append(NSMutableDictionary()) | |
let parser = XMLParser(data: data) | |
parser.delegate = self | |
parser.parse() | |
return stack.first as? [String : Any] | |
} | |
} | |
// MARK: - XMLParserDelegate | |
extension XMLToDict: XMLParserDelegate { | |
public func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { | |
guard let parent = stack.last else { | |
fatalError() | |
} | |
let child = NSMutableDictionary() | |
if attributeDict.count > 0 { | |
child.setObject(attributeDict, forKey: XMLToDict.kAttributes as NSString) | |
} | |
if let existingValue = parent[elementName] { | |
let array: NSMutableArray | |
if let currentArray = existingValue as? NSMutableArray { | |
array = currentArray | |
} else { | |
array = NSMutableArray() | |
array.add(existingValue) | |
parent[elementName] = array | |
} | |
array.add(child) | |
} else { | |
parent[elementName] = child | |
stack[stack.endIndex - 1] = parent | |
} | |
stack.append(child) | |
} | |
public func parser(_ parser: XMLParser, foundCharacters string: String) { | |
let trimmedString = string.trimmingCharacters(in: .whitespacesAndNewlines) | |
textBeingProcessed.append(trimmedString) | |
} | |
public func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { | |
guard let lastDict = stack.last else { | |
fatalError() | |
} | |
let parent = stack[stack.endIndex - 2] | |
if textBeingProcessed.count > 0 { | |
if lastDict.count > 0 { | |
lastDict[XMLToDict.kText] = textBeingProcessed | |
} else if let array = parent[elementName] as? NSMutableArray { | |
array.removeLastObject() | |
array.add(textBeingProcessed) | |
} else { | |
parent[elementName] = textBeingProcessed | |
} | |
} else if lastDict.count == 0 { | |
parent.removeObject(forKey: elementName) | |
} | |
textBeingProcessed = "" | |
stack.removeLast() | |
} | |
public func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) { | |
print(parseError) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment