Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在iOS Swift中获取XML数据并在tableview中绑定?_Ios_Swift_Xml_Odata_Alamofire - Fatal编程技术网

如何在iOS Swift中获取XML数据并在tableview中绑定?

如何在iOS Swift中获取XML数据并在tableview中绑定?,ios,swift,xml,odata,alamofire,Ios,Swift,Xml,Odata,Alamofire,我一直在使用基本授权的ODataURL。XML格式的oData响应。我可以使用Alamofire从ODataURL响应数据。但我无法从XML中获得特定的值 以下是我的XML响应数据: <feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/a

我一直在使用基本授权的ODataURL。XML格式的oData响应。我可以使用Alamofire从ODataURL响应数据。但我无法从XML中获得特定的值

以下是我的XML响应数据:

 <feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://hostname:portNumber/sap/opu/odata/sap/ZPRJ_PM_APPS_IH_SRV/">
<id>hostname:portNumber/sap/opu/odata/sap/ZPRJ_PM_APPS_IH_SRV/WorkOrder</id>
<title type="text">WorkOrderF4Set</title>
<updated>2019-08-16T15:37:48Z</updated>
<author>
    <name/>
</author>
<link href="WorkOrderF4Set" rel="self" title="WorkOrderF4Set"/>
<entry>
    <id>hostname:portNumber/sap/opu/odata/sap/ZPRJ_PM_APPS_IH_SRV/WorkOrder('000000504780')</id>
    <title type="text">WorkOrder('000000504780')</title>
    <updated>2019-08-16T15:37:48Z</updated>
    <category term="ZPRJ_PM_APPS_IH_SRV.WorkOrder" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
    <link href="WorkOrder('000000504780')" rel="self" title="WorkOrder"/>
    <content type="application/xml">
        <m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
            <d:WorkOrder>000000504780</d:WorkOrder>
            <d:Description>General Maintenance testing</d:Description>
        </m:properties>
    </content>
</entry>
<entry>
    <id>http://hostname:portNumber/sap/opu/odata/sap/ZPRJ_PM_APPS_IH_SRV/WorkOrder('000000821400')</id>
    <title type="text">WorkOrderF4Set('000000821400')</title>
    <updated>2019-08-16T15:37:48Z</updated>
    <category term="ZPRJ_PM_APPS_IH_SRV.WorkOrder" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
    <link href="WorkOrder('000000821400')" rel="self" title="WorkOrder"/>
    <content type="application/xml">
        <m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
            <d:WorkOrder>000000821400</d:WorkOrder>
            <d:Description>PUMP LEAKING</d:Description>
        </m:properties>
    </content>
</entry>
</feed> 
还尝试使用XMLSwiftyParser吊舱,但效果不理想

  let data = stringg.data(using: .utf8)



                    let xml = try! XML.parse(data!)

                    print("xml value:\(xml)")



                    let element = xml.feed.entry

                    print("element xml :\(element)")



                    let results = xml["feed", "entry"]

                    print("result xml :\(results)")





                    for result in results["entry"] {

                        if let jobtitle = result["d:WorkOrder"].text {

                            print("job::\(jobtitle)")

                        }

                    }
如何在表视图中解析d:WorkOrder和d:Description


非常感谢您的任何帮助…

您可以使用此代码解析任何xml数据。然后可以访问parsedData变量中的数据。使用助手函数“search”,您可以获得任意键的任何值

class ViewController: UIViewController, XMLParserDelegate {

    var parsedData = Dictionary<String,Any>()
    var openElements = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        if let path = Bundle.main.url(forResource: "Feed", withExtension: "xml") {
            if let parser = XMLParser(contentsOf: path) {
                parser.delegate = self
                parser.parse()
            }
        }
    }

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        openElements.append(elementName)

        parsedData[elementName] = attributeDict
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        _ = openElements.popLast()

        if let last = openElements.last, var dict = parsedData[last] as? [String:Any], let data = parsedData[elementName] {
            if let prevData = dict[elementName] {
                dict[elementName] = [prevData, data]
            } else {
                dict[elementName] = data
            }

            parsedData[last] = dict

            parsedData.removeValue(forKey: elementName)
        }
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        let string = string.trimmingCharacters(in: .whitespacesAndNewlines)
        if !string.isEmpty, let last = openElements.last, var dict = parsedData[last] as? [String:Any] {
            dict["text"] = string

            parsedData[last] = dict
        }
    }

    func parserDidEndDocument(_ parser: XMLParser) {
        search(key: "d:WorkOrder", in: parsedData, completion: { print($0) })
        search(key: "d:Description", in: parsedData, completion: { print($0) })
    }

    func search(key:String, in dict:[String:Any], completion:((Any) -> ())) {
        if let foundValue = dict[key] {
            completion(foundValue)
        } else {
            dict.values.enumerated().forEach {
                if let innerDict = $0.element as? [String:Any] {
                    search(key: key, in: innerDict, completion: completion)
                }

                if let innerArray = $0.element as? [[String:Any]] {
                    innerArray.forEach({ innerDict in
                        search(key: key, in: innerDict, completion: completion)
                    })
                }
            }
        }
    }
}
类ViewController:UIViewController,XMLParserDelegate{
var parsedData=字典()
var openElements=[String]()
重写func viewDidLoad(){
super.viewDidLoad()
如果let path=Bundle.main.url(forResource:“Feed”,扩展名为“xml”){
如果let parser=XMLParser(contentsOf:path){
parser.delegate=self
parser.parse()
}
}
}
func解析器(parser:XMLParser,DidStartElementName:String,namespaceURI:String?,qualifiedName qName:String?,attributes attributeDict:[String:String]=[:])){
openElements.append(elementName)
parsedData[elementName]=属性指令
}
func解析器(解析器:XMLParser,didEndElement元素名称:String,namespaceURI:String?,qualifiedName qName:String?){
_=openElements.popLast()
如果let last=openElements.last,var dict=parsedData[last]as?[String:Any],则let data=parsedData[elementName]{
如果let prevData=dict[elementName]{
dict[elementName]=[prevData,data]
}否则{
dict[elementName]=数据
}
parsedData[last]=dict
parsedData.removeValue(forKey:elementName)
}
}
func解析器(parser:XMLParser,foundCharacters string:string){
let string=string.trimmingCharacters(在:。空格和换行符中)
如果!string.isEmpty,则让last=openElements.last,var dict=parsedData[last]as?[string:Any]{
dict[“text”]=字符串
parsedData[last]=dict
}
}
func parserDidEndDocument(parser:XMLParser){
搜索(关键字:“d:WorkOrder”,输入:parsedData,完成:{print($0)})
搜索(关键字:“d:Description”,输入:parsedData,完成:{print($0)})
}
func搜索(关键字:String,在dict:[String:Any]中),完成:((Any)->()){
如果let foundValue=dict[key]{
完成(价值)
}否则{
dict.values.enumerated().forEach{
如果让innerDict=$0.0元素为?[字符串:任意]{
搜索(key:key,in:innerDict,completion:completion)
}
如果让innerArray=$0.0作为元素?[[String:Any]]{
forEach({innerDict in
搜索(key:key,in:innerDict,completion:completion)
})
}
}
}
}
}

基于@HamzaÖztürk答案,尝试使用XMLParse:

 import UIKit

 struct Book {
   var workOrder: String
   var description: String
 }

 class TableViewController: UITableViewController, XMLParserDelegate {

var books: [Book] = []
var elementName: String = String()
var bookWorkOrder = String()
var bookdescription = String()


override func viewDidLoad() {
    super.viewDidLoad()



    if let path = Bundle.main.url(forResource: "Feed", withExtension: "xml") {
        if let parser = XMLParser(contentsOf: path) {
            parser.delegate = self
            parser.parse()
        }
     }
   }

   // 1
   func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {

    if elementName == "entry" {
        bookWorkOrder = String()
        bookdescription = String()
    }

    self.elementName = elementName

    }

    // 2
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "entry" {
        let book = Book(workOrder: bookWorkOrder, description: bookdescription)
        books.append(book)
        print("count::\(books.count)")


       }
   }

   // 3
   func parser(_ parser: XMLParser, foundCharacters string: String) {
    let data = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)

    if (!data.isEmpty) {
        if self.elementName == "d:WorkOrder" {
            bookWorkOrder += data
        } else if self.elementName == "d:Description" {
            bookdescription += data
        }
     }
   }



   // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
    // return the number of sections
    return 1
   }

      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // return the number of rows

    return books.count
   }


      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! cellTableViewCell

    let book = books[indexPath.row]
    print("book::\(book.workOrder)")

    cell.workorfer.text = book.workOrder
    cell.descriptor.text = book.description


    return cell
   }




}
你也可以试试pod

使用嵌套映射功能,您的模型可能如下所示:

class Feed: XMLMappable {
    var nodeName: String!

    var entries: [Entry]?

    required init?(map: XMLMap) {}

    func mapping(map: XMLMap) {
        entries <- map["entry"]
    }
}

class Entry: XMLMappable {
    var nodeName: String!

    var workOrder: String?
    var description: String?

    required init?(map: XMLMap) {}

    func mapping(map: XMLMap) {
        workOrder <- map["content.m:properties.d:WorkOrder"]
        description <- map["content.m:properties.d:Description"]
    }
}
或者使用亚种:

Alamofire.request(url,方法:.get,编码:URLEncoding.default,头:头)
.responseXMLObject{(dataResponse:dataResponse)位于
让feed=dataResponse.result.value
打印(feed?.toXMLString()??“nil”)
}

如何在tableview中使用,效果很好。我需要在tableview中加载d:WorkOrder和d:Description
class Feed: XMLMappable {
    var nodeName: String!

    var entries: [Entry]?

    required init?(map: XMLMap) {}

    func mapping(map: XMLMap) {
        entries <- map["entry"]
    }
}

class Entry: XMLMappable {
    var nodeName: String!

    var workOrder: String?
    var description: String?

    required init?(map: XMLMap) {}

    func mapping(map: XMLMap) {
        workOrder <- map["content.m:properties.d:WorkOrder"]
        description <- map["content.m:properties.d:Description"]
    }
}
let feed = Feed(XMLString: xmlString)
Alamofire.request(url, method: .get, encoding: URLEncoding.default, headers: headers)
    .responseXMLObject { (dataResponse: DataResponse<Feed>) in
        let feed = dataResponse.result.value
        print(feed?.toXMLString() ?? "nil")
}