Simple XML Parser implemented in Swift
This is a XML parser inspired by SwiftyJSON and SWXMLHash.
NSXMLParser in Foundation framework is a kind of "SAX" parser. It has enough performance but is a little inconvenient. So we have implemented "DOM" parser wrapping it.
- access XML Document with "subscript".
- access XML Document as Sequence.
- easy debugging XML pathes.
- iOS 7.0+
- Swift 2.0+
github "https://github.com/yahoojapan/SwiftyXMLParser"
> carthage update
platform :ios, '8.0'
use_frameworks!
pod "SwiftyXMLParser", :git => 'https://github.com/yahoojapan/SwiftyXMLParser.git'
> pod install
let string = "<ResultSet><Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result></ResultSet>"
// parse xml document
xml = try! XML.parse(string)
// access xml element
let accessor = xml["ResultSet"]
// access XML Text
let text = xml["ResultSet", "Result", "Hit", 0, "Name"].text {
print("exsists path & text in XML Element")
}
// access XML Attribute
let index = xml["ResultSet", "Result", "Hit"].attributes?["index"] {
print("exsists path & an attribute in XML Element")
}
// enumerate child Elements in the parent Element
for hit in xml["ResultSet", "Result", "Hit"] {
print("enumarate existing XML Elements")
}
// check if the XML path is wrong
if case .Failure(let error) = xml["ResultSet", "Result", "TypoKey"] {
print(error)
}
- from String
let string = "<ResultSet><Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result></ResultSet>"
xml = try! XML.parse(string) // -> XML.Accessor
- from NSData
let string = "<ResultSet><Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result></ResultSet>"
let data = string.dataUsingEncoding(NSUTF8StringEncoding)
xml = XML.parse(data) // -> XML.Accessor
let element = xml["ResultSet"] // -> XML.Accessor
- with String
let element = xml["ResultSet"]["Result"] // -> <Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result>
- with Array
let path = ["ResultSet", "Result"]
let element = xml[path] // -> <Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result>
- with Variadic
let element = xml["ResultSet", "Result"] // -> <Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result>
let element = xml["ResultSet", "Result", "Hit", 1] // -> <Hit index=\"2\"><Name>Item2</Name></Hit>
if let attributeValue = xml["ResultSet", "Result", "Hit", 1].attributes?["index"] {
print(attributeValue) // -> 2
}
- with optional binding
if let text = xml["ResultSet", "Result", "Hit", 1, "Name"].text {
print(text) // -> Item2
}
- with custom operation
struct Entity {
var name = ""
}
let entity = Entity()
entity.name ?= xml["ResultSet", "Result", "Hit", 1, "Name"].text // assign if it has text
- convert Int and assign
struct Entity {
var name: Int = 0
}
let entity = Entity()
entity.name ?= xml["ResultSet", "Result", "Hit", 1, "Name"].int // assign if it has Int
and there are other syntax sugers, bool, url and double.
- assign text into Array
struct Entity {
var names = [String]()
}
let entity = Entity()
entity.names ?<< xml["ResultSet", "Result", "Hit", 1, "Name"].text // assign if it has text
print(xml["ResultSet", "Result", "TypoKey"]) // -> "TypoKey not found."
- for-in
for element in xml["ResultSet", "Result", "Hit"] {
print(element.text)
}
- map
xml["ResultSet", "Result", "Hit"].map { $0["Name"].text }
SwiftyXMLParser goes well with Alamofire. You can parse the response easily.
import Alamofire
import SwiftyXMLParser
Alamofire.request(.GET, "https://itunes.apple.com/us/rss/topgrossingapplications/limit=10/xml")
.responseData { response in
if let data = response.data {
let xml = XML.parse(data)
print(xml["feed", "entry", 0, "title"].text) // outputs the top title of iTunes app raning.
}
}
In addition, there is the extension of Alamofire to combine with SwiftyXMLPraser.
This software is released under the MIT License, see LICENSE.