Reputation: 7863
I'm new to Swift and I'm trying to create an OSX terminal app to parse an xml file. I've got it reading the file in to a string, but cannot figure out how parse it in to a structure I can then navigate and pull data from. It appears that NSXMLDocument seems to want a URL and NSXMLParser needs a delegate, but my initial attempts could not get them to work.
Here's what I've got so far:
import Foundation
import Cocoa
let path = "//Users/<path>/someFile.xml"
var err: NSError?
let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: &err)
The structure of the xml file is something like this:
<?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>
Your help is much appreciated.
Upvotes: 1
Views: 6349
Reputation: 4902
The NSXMLDocument
usage would look like:
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() {
// ...
}
}
Upvotes: 2
Reputation: 23078
Parsing an XML document is not that trivial and cannot be done with a one-liner in code.
To parse it with NSXMLParser
you need a custom class that implements the NSXMLParserDelegate
protocol, like this:
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!) {
...
}
}
So whenever you retrieve a new element with didStartElement
you have to check what element it is and what child elements you expect further. This all depends on the structure of your XML document so there is no all in one solution one can give you.
Upvotes: 2