首页 > 解决方案 > 如何解析 XML - Swift 3 中的复杂 XML 构造

问题描述

我必须在我的应用程序中解析 xml 文件。我使用令牌从 Web 服务获取 xml 数据。我无法解析真正的 xml 标签的数据,因为 xml 文件是一个复杂的结构,并且一些标签会重复几次。例如 xml 文件有 17 个“cbc:ID”标签。我需要将第一个 cbc:ID 标签放入“发票”标签中。 这是我的 xml 数据的示例。我使用那个功能;

func getXMLDataFromServer(authorization:String){
        let url = NSURL(string: self.urlString)
        let request = NSMutableURLRequest(url: url! as URL)
        request.httpMethod = "GET"
        request.addValue(authorization, forHTTPHeaderField: "Authorization")
        let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in

            if error != nil {
                //print("\(error)")
            }

            else {

                let htmlContent = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                //print("\(htmlContent)")

            }
            if let receivedData = data {
                if let aString = String(data: receivedData, encoding: String.Encoding.utf8) {
                    if let percentage = aString.addingPercentEncoding(withAllowedCharacters:CharacterSet(charactersIn:"ıİöÖçÇüÜğĞşŞ").inverted) {
                        if let aData = percentage.data(using: String.Encoding.utf8) {
                            let parser = XMLParser(data: aData)
                            parser.delegate = self
                            parser.parse()
                        }
                    }
                }
            }
        }
        task.resume()
    }
//MARK:- XML Delegate methods
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?,

属性 attributeDict: [String : String] = [:]) { currentParsingElement = elementName if elementName == "Invoice" { print("开始解析...") } print(elementName) }

func parser(_ parser: XMLParser, foundCharacters string: String) {
    let foundedChar = string.trimmingCharacters(in:NSCharacterSet.whitespacesAndNewlines)

    if (!foundedChar.isEmpty) {
        if currentParsingElement == "cbc:ID" {
            ipAddr += foundedChar
        }
        else if currentParsingElement == "cbc:Name" {
            countryCode += foundedChar
        }
        else if currentParsingElement == "CountryName" {
            countryName += foundedChar
        }

    }
    print(foundedChar)
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "Invoice" {
        print("Ended parsing...")
    }

    print(elementName)

}

func parserDidEndDocument(_ parser: XMLParser) {
    DispatchQueue.main.async {
        // Update UI
        //self.displayOnUI()

    }
}

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

我已经尝试过该教程来解析我的 xml 数据。但是我无法解析我的 xml 数据中的真实标签。

我需要一些标签的数据,“发票”标签中有“cbc:ID”标签的数据,“cac:AccountingCustomerParty”标签中有“cbc:Name”标签的数据,还有“cbc:ID”标签,但它是“cac:AccountingCustomerParty " 和 "cac:LegalMonetaryTotal" 中的 "cbc:PayableAmount" 标签数据

有人知道如何为我的应用程序解析真实标签的数据吗?

标签: swiftxmlparsing

解决方案


解析如此复杂的 XMLXMLParser非常困难。

如果您不介意使用外部库,可以尝试XMLMapper

实际上,使用嵌套映射很容易。您可以拥有以下模型类:

class Invoice: XMLMappable {
    var nodeName: String!

    var cbcID: String?
    var partyName: String?
    var partyCBCID: PartyCBCID?
    var payableAmount: PayableAmount?

    required init?(map: XMLMap) { }

    func mapping(map: XMLMap) {
        cbcID <- map["cbc:ID"]
        partyName <- map["cac:AccountingCustomerParty.cac:Party.cac:PartyName.cbc:Name"]
        partyCBCID <- map["cac:AccountingCustomerParty.cac:Party.cac:PartyIdentification.cbc:ID"]
        payableAmount <- map["cac:LegalMonetaryTotal.cbc:PayableAmount"]
    }

}

class PartyCBCID: XMLMappable {
    var nodeName: String!

    var schemeID: String?
    var id: String?

    required init?(map: XMLMap) { }

    func mapping(map: XMLMap) {
        schemeID <- map.attributes["schemeID"]
        id <- map.innerText
    }

}

class PayableAmount: XMLMappable {
    var nodeName: String!

    var currencyID: String?
    var amount: Double?

    required init?(map: XMLMap) { }

    func mapping(map: XMLMap) {
        currencyID <- map.attributes["currencyID"]
        amount <- map.innerText
    }
}

map(XMLString:)您可以使用以下函数映射您的 XML 字符串XMLMapper

let invoice = XMLMapper<Invoice>().map(XMLString: xmlString)
print(invoice?.cbcID ?? "nil") // access cbc:ID for example 

试试看。


推荐阅读