import Foundation
import FoundationXML

class XMLDictionaryParser: NSObject, XMLParserDelegate {
    private var dictionaryStack: [[String: Any]] = []
    private var textInProgress: String = ""

    func parse(data: Data) -> [String: Any]? {
        let parser = XMLParser(data: data)
        parser.delegate = self
        guard parser.parse() else {
            return nil
        }
        return dictionaryStack.first
    }

    // MARK: - XMLParserDelegate

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
        var dict: [String: Any] = [:]
        for (key, value) in attributeDict {
            if let intValue = Int(value) {
                dict[key] = intValue
            } else {
                dict[key] = value
            }
        }
        dictionaryStack.append(dict)
        textInProgress = ""
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        textInProgress += string
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        var dict = dictionaryStack.popLast()!
        if !textInProgress.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            if let intValue = Int(textInProgress.trimmingCharacters(in: .whitespacesAndNewlines)) {
                dict[elementName] = intValue
            } else {
                dict[elementName] = textInProgress.trimmingCharacters(in: .whitespacesAndNewlines)
            }
        }

        if var top = dictionaryStack.last {
            if let existingValue = top[elementName] {
                if var array = existingValue as? [[String: Any]] {
                    array.append(dict)
                    top[elementName] = array
                } else {
                    top[elementName] = [existingValue, dict]
                }
            } else if dict.count == 1, let key = dict.keys.first, let value = dict[key] {
                top[elementName] = value
            } else {
                top[elementName] = dict
            }
            dictionaryStack[dictionaryStack.count - 1] = top
        } else {
            dictionaryStack.append(dict)
        }
        textInProgress = ""
    }
}

// Example Usage

let XMLString = """
<root>
    <person>
        <name>John Doe</name>
        <age>30</age>
        <address>New York, USA</address>
    </person>
    <person>
        <name>Jane Smith</name>
        <age>25</age>
        <address>London, UK</address>
    </person>
</root>
"""
if let XMLdata = XMLString.data(using: .utf8) {
    let parser = XMLDictionaryParser()
    if let parsedDictionary = parser.parse(data: XMLdata) {
        if let root = parsedDictionary["root"] as? [String: Any],
           let persons = root["person"] as? [[String: Any]] {
            for person in persons {
                if let name = person["name"] as? String {
                    print(name)
                }
            }
        }
    } else {
        print("Parsing failed")
    }
} else {
    print("Invalid XML string")
}