使用 NSXMLParser 在 Swift 中解析分层 XML [英] Parsing Hierarchical XML in Swift using NSXMLParser

查看:71
本文介绍了使用 NSXMLParser 在 Swift 中解析分层 XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很难以我可以实际使用的形式获取分层 XML 值,因此非常感谢任何帮助.我对 Swift 和 IOS 开发还很陌生,所以说实话我并不完全理解解析器,但我希望在这之后我会!

I'm really having problems getting hierarchical XML values back in a form that I can actually use, so any assistance would be much appreciated. I'm pretty new to Swift and IOS development, so to be honest I do not fully understand the parser, but I am hopeful after this that I will!

这是我试图解析的一个 XML 示例,它来自一个soap Web 服务.在连接和获取数据方面的所有方面都运行良好

Here's an example XML that I am trying to parse, this comes back from a soap web service. All that side in terms of connecting and getting the data works perfectly fine

<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <get_Entry_DetailsResponse
            xmlns="http://tempuri.org/">
            <get_Entry_DetailsResult>
                <ApiResult
                    xmlns="">
                    <Status>Success</Status>
                    <Parameters>
                        <TotalRecords>1</TotalRecords>
                        <Records>
                            <Entry>
                                <Entry_ID>1234</Entry_ID>
                                <Title>This is the Title</Title>
                                <Description>This is a description.</Description>
                                <Charge_USD>3</Charge_USD>
                                <Charge_GBP>1.5</Charge_GBP>
                                <Classifications>
                                    <Classification_Type>No. Of Colours</Classification_Type>
                                    <Description>10</Description>
                                    <Classification_Type>Height</Classification_Type>
                                    <Description>16.712</Description>
                                    <Classification_Type>Width</Classification_Type>
                                    <Description>1.485</Description>
                                    <Classification_Type>Width Count</Classification_Type>
                                    <Description>11</Description>
                                    <Classification_Type>Pages</Classification_Type>
                                    <Description>6</Description>
                                    <Classification_Type>Type</Classification_Type>
                                    <Description>Type Description</Description>
                                    <Classification_Type>Topic</Classification_Type>
                                    <Description>Transport</Description>
                                    <Classification_Type>Item</Classification_Type>
                                    <Description>Shop Item</Description>
                                    <Classification_Type>Material</Classification_Type>
                                    <Description>Metal</Description>
                                    <Classification_Type>Manufacturer</Classification_Type>
                                    <Description>Unknown</Description>
                                </Classifications>
                            </Entry>
                        </Records>
                    </Parameters>
                </ApiResult>
            </get_Entry_DetailsResult>
        </get_Entry_DetailsResponse>
    </s:Body>
</s:Envelope>

这样我就可以获得 Entry_ID、Title、Description、Charge_GBP 和 Charge_USD 之类的元素,这是如何将分类重新放入代码中,以便我可以实际使用它在页面上输出它.

So I can get elements like the Entry_ID, Title, Description, Charge_GBP and Charge_USD fine, it's how to get the classifications back into the code so I can actually use it to output it on the page.

这里是我的 connectionDidFinishLoading,我在这里启动解析器并运行:

So here is my connectionDidFinishLoading, where I start the parser off and running:

func connectionDidFinishLoading(connection: NSURLConnection!) {
    var xmlParser = NSXMLParser(data: mutableData)
    xmlParser.delegate = self
    xmlParser.parse()
    xmlParser.shouldResolveExternalEntities = true
}

然后这里是 XMLParser Delegate 的东西:

Then here is the XMLParser Delegate stuff:

var mutableData:NSMutableData  = NSMutableData.alloc()
var currentElementName:NSString = ""
var foundCharacters = ""
var appParsedData = [Dictionary<String, String>]()
var currentDataDictionary = Dictionary<String, String>()

func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: NSDictionary!) {

        currentElementName = elementName

    }

func parser(parser: NSXMLParser, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {

    if !foundCharacters.isEmpty {
        currentDataDictionary[currentElementName] = foundCharacters
        foundCharacters = ""

        //Last Element so add to main Dictionary
        //Cannot find last element yet on XML so use Charge_GBP for testing until fixed
        if currentElementName == "Charge_GBP" {
            appParsedData.append(currentDataDictionary)
        }
    }
}

func parser(parser: NSXMLParser, foundCharacters string: String!) {
    if (currentElementName == "Entry_ID") || (currentElementName == "Title") || currentElementName == "Description" || currentElementName == "Charge_USD" || currentElementName == "Charge_GBP" || currentElementName == "Classification_Type" {
        foundCharacters += string
    }
}

func parserDidEndDocument(parser: NSXMLParser!) {

    self.setupItemsOnView()

}

然后我的 setupItemsOnView 函数是我打算获取值并将它们显示在视图控制器上的位置:

Then my setupItemsOnView function which is where I intend to get the values and display them on the view controller so far is:

func setupItemsOnView() {

    for (currentElementName) in appParsedData {
        println("\(currentElementName):")
    }

    let test = appParsedData[0] as Dictionary<String, String>
    let test_entryid = test["Entry_ID"]
    println("Entry ID is \(test_entryid)")

}

嗯,好的,所以基本上我可以在 setupItemsOnView 函数中获取值 Entry_ID、Title、Description、Charge_GBP 和 Charge_USD,但是使用这种方法我无法从分类父级以有意义的方式获取分类和描述值.我目前正在使用字典来存储数据,所以我想知道当您拥有分层 XML 时使用字典是否正确,但我不知道还能尝试什么.

Phew, ok, so basically I can get the values Entry_ID, Title, Description, Charge_GBP and Charge_USD in the setupItemsOnView function, but using this method I cannot get the classifications and descriptions values back in a meaningful way from the classifications parent. I'm currently using as you can see a dictionary to store the data, so I wonder if using a Dictionary is the right thing to do or not when you have hierarchical XML, but I have no idea what else to try.

从我的背景来看,您可以使用点表示法引用 XML,只需在所有元素的父级周围循环,但我无法快速实现这一点,所以我只需要一种可用的方法来获取以我可以输出的形式备份所有数据.

From my background you'd be able to reference the XML with a dot notation and just loop around the parent for all the elements, but I can't get that working in swift, so I just need a usable way to get back the all data in a form that I can then output.

您可以提供任何有助于解决此问题的代码,我们将不胜感激.

Any code you may offer to help with this would be greatly appreciated.

干杯

D

推荐答案

您想要的是类似于 Swift 的 jaxb 的东西——但我不知道它存在.无论如何,在 Swift 中解析类似于使用 SAX 解析器.据推测,您的 Swift 代码中有一个类层次结构,对应于 XML 中的元素层次结构.我使用的方法是有状态的——只需实例化与解析元素对应的类,并将其保存在为此目的指定的变量中.然后,您的解析代码可以填充在后续回调中遇到的类数据.当然,您必须分层执行此操作,并使用 didEndElement 回调来检测完成.

What you'd like is something comparable to jaxb for Swift -- but I'm not aware that it exists. Anyway, parsing in Swift is akin to using a SAX parser. Presumably, you have an class hierarchy in your Swift code that corresponds to the element hierarchy in the XML. The approach I used was stateful -- just instantiate the class corresponding to the element parsed, and keep it in a variable designated for that purpose. Then, your parsing code can populate the class data as it is encountered in subsequent callbacks. Of course, you have to do this hierarchically, and use the didEndElement callback to detect completion.

这篇关于使用 NSXMLParser 在 Swift 中解析分层 XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆