如何在OSX上解析Swift 6.1中的XML字符串?
问题描述:
我是新来的Swift,我试图创建一个OSX终端应用程序来解析一个XML文件。我已经将它读入一个字符串中,但无法弄清楚如何将它解析为一个结构,然后我可以导航并从中提取数据。看起来NSXMLDocument似乎需要一个URL,而NSXMLParser需要一个委托,但我最初的尝试无法让他们工作。如何在OSX上解析Swift 6.1中的XML字符串?
这里是我到目前为止有:
import Foundation
import Cocoa
let path = "//Users/<path>/someFile.xml"
var err: NSError?
let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: &err)
的XML文件的结构是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Documents>
<List>
<Document name="name1" type="TYPE1" date="some string">
<Items>
<Item name="item1" dataType="DATATYPE1" version="1">
<Item name="item2" dataType="DATATYPE9" version="4">
</Items>
</Document>
<Document name="name2" type="TYPE4" date="some string">
...
</List>
</Documents>
</Data>
你的帮助是非常赞赏。
答
解析XML文档并不是那么简单,不能用代码中的单行代码完成。
要与NSXMLParser
解析它,你需要一个实现NSXMLParserDelegate
协议的自定义类,像这样:
class myXMLParser: NSObject, NSXMLParserDelegate {
...
func parseFile(filename: String) {
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: "xml")
if let parser = NSXMLParser(contentsOfURL: url) {
parser.delegate = self
parser.parse()
}
}
func parserDidStartDocument(parser: NSXMLParser!) {
...
}
func parserDidEndDocument(parser: NSXMLParser!) {
...
}
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
...
}
func parser(parser: NSXMLParser!, foundCharacters string: String!) {
...
}
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
...
}
}
所以每当你检索新的元素与didStartElement
你要检查它是什么元素,什么孩子元素你期望更进一步。这一切都取决于你的XML文档的结构,所以在一个解决方案中你可能不会提供所有的解决方案。
答
的NSXMLDocument
使用看起来像:
let fm = NSFileManager.defaultManager()
var err : NSError?
let userDirectory = fm.URLForDirectory(.UserDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false, error: &err)
if err != nil {
// ...
}
if let path = userDirectory?.URLByAppendingPathComponent("someFile.xml") {
NSXMLDocument(contentsOfURL: configURL, options: 0, error: &err)
if err != nil {
// ...
}
if let rootNode = config?.rootElement() {
// ...
}
}