将Xml解析为Array(Swift)

时间:2016-08-05 06:47:53

标签: swift

 struct person{
    var name = " "
    var sex = " "
    var age = " "
    }

var personArray: [person] = []

我的Xml字符串包含两组数据

<a>
<name> abc </name>
<sex> male </sex>
<age> 13   </age>
</a>
<a>
<name> bcd </name>
<sex> male </sex>
<age> 14   </age>
</a>

如何将此xml字符串解析为personArray?我知道如何将xml字符串解析为单个对象。但我不知道如何将其解析为Array。

1 个答案:

答案 0 :(得分:2)

您可以使用NSXMLParser(或XMLParser,因为它现在在Swift 3中)。 NSXMLDocument也是一种可能性,但iOS不可用,而XMLParser在所有操作系统上都可用。这是您案例的简单实现......

struct Person { // NB capitalised your type - it's good practice
    var name = " "
    var sex = " "
    var age = " "
}
let inputString = "<a><name> abc </name><sex> male </sex><age> 13   </age></a><a><name> bcd </name><sex> male </sex><age> 14   </age></a>"

// Wrap it up or it won't be valid XML
let document = "<doc>" + inputString + "</doc>" 

// We can create a parser from a URL, a Stream, or NSData.
if let data = document.data(using: .utf16) { // Get the NSData
    let xmlParser = XMLParser(data: data) 
    let delegate = MyDelegate() // This is your own delegate - see below
    xmlParser.delegate = delegate 
    if xmlParser.parse() {
        print("Result \(delegate.personArray)")
        // "Result [Person(name: " abc ", sex: " male ", age: " 13   "), Person(name: " bcd ", sex: " male ", age: " 14   ")]\n" - as required
    }
}

class MyDelegate: NSObject, XMLParserDelegate {
    // Simple state machine to capture fields and add completed Person to array
    var personArray: [Person] = []
    enum State { case none, name, sex, age }
    var state: State = .none
    var newPerson: Person? = nil

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
        switch elementName {
        case "a" :
            self.newPerson = Person()
            self.state = .none
        case "sex":
            self.state = .sex
        case "name":
            self.state = .name
        case "age":
            self.state = .age
        default:
            self.state = .none
        }
    }
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        if let newPerson = self.newPerson, elementName == "a" {
            self.personArray.append(newPerson)
            self.newPerson = nil
        }
        self.state = .none
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        guard let _ = self.newPerson else { return }
        switch self.state {
        case .name:
            self.newPerson!.name = string
        case .age:
            self.newPerson!.age = string
        case .sex:
            self.newPerson!.sex = string
        default:
            break
        }
    }

    func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
    }            
}

要让它在Playgrounds中运行,你需要首先声明委托(在调用之上),但这样做会更好......