Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.

Commit 2469c10

Browse files
Updated to support changes to the Swift Language in Xcode 6 beta 5. Also updated SWXMLHash to latest commit.
1 parent 2447ed4 commit 2469c10

File tree

8 files changed

+279
-317
lines changed

8 files changed

+279
-317
lines changed

GovDataRequest.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,14 @@ class GovDataRequest {
116116
var err: NSError?
117117
if self.responseFormat == "JSON" {
118118
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
119-
if(err?) {
119+
if(err != nil) {
120120
// If there is an error parson JSON, print it to the console
121121
NSLog ("Error parsing the JSON")
122122
}
123123
self.delegate?.didCompleteWithDictionary(jsonResult)
124124
} else if self.responseFormat == "XML" {
125-
let parser = SWXMLHash()
126125
var dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
127-
let xml = parser.parse(dataString)
126+
let xml = SWXMLHash.parse(dataString)
128127
self.delegate?.didCompleteWithXML(xml)
129128
}
130129
})

SWXMLHash.swift

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
//
2+
// SWXMLHash.swift
3+
//
4+
// Copyright (c) 2014 David Mohundro
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in
14+
// all copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
// THE SOFTWARE.
23+
24+
import Foundation
25+
26+
/// Simple XML parser.
27+
public class SWXMLHash {
28+
/**
29+
Method to parse XML passed in as a string.
30+
31+
:param: xml The XML to be parsed
32+
33+
:returns: An XMLIndexer instance that is used to look up elements in the XML
34+
*/
35+
class public func parse(xml: String) -> XMLIndexer {
36+
return parse((xml as NSString).dataUsingEncoding(NSUTF8StringEncoding))
37+
}
38+
39+
/**
40+
Method to parse XML passed in as an NSData instance.
41+
42+
:param: xml The XML to be parsed
43+
44+
:returns: An XMLIndexer instance that is used to look up elements in the XML
45+
*/
46+
class public func parse(data: NSData) -> XMLIndexer {
47+
var parser = XMLParser()
48+
return parser.parse(data)
49+
}
50+
}
51+
52+
/// The implementation of NSXMLParserDelegate and where the parsing actually happens.
53+
class XMLParser : NSObject, NSXMLParserDelegate {
54+
var parsingElement: String = ""
55+
56+
override init() {
57+
currentNode = root
58+
super.init()
59+
}
60+
61+
var lastResults: String = ""
62+
63+
var root = XMLElement(name: "root")
64+
var currentNode: XMLElement
65+
var parentStack = [XMLElement]()
66+
67+
func parse(data: NSData) -> XMLIndexer {
68+
// clear any prior runs of parse... expected that this won't be necessary, but you never know
69+
parentStack.removeAll(keepCapacity: false)
70+
root = XMLElement(name: "root")
71+
72+
parentStack.append(root)
73+
74+
let parser = NSXMLParser(data: data)
75+
parser.delegate = self
76+
parser.parse()
77+
78+
return XMLIndexer(root)
79+
}
80+
81+
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName: String!, attributes attributeDict: NSDictionary!) {
82+
83+
self.parsingElement = elementName
84+
85+
currentNode = parentStack[parentStack.count - 1].addElement(elementName, withAttributes: attributeDict)
86+
parentStack.append(currentNode)
87+
88+
lastResults = ""
89+
}
90+
91+
func parser(parser: NSXMLParser!, foundCharacters string: String!) {
92+
lastResults += string
93+
}
94+
95+
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
96+
if !lastResults.isEmpty {
97+
currentNode.text = lastResults
98+
}
99+
100+
parentStack.removeLast()
101+
}
102+
}
103+
104+
/// Returned from SWXMLHash, allows easy element lookup into XML data.
105+
public enum XMLIndexer {
106+
case Element(XMLElement)
107+
case List([XMLElement])
108+
case Error(NSError)
109+
110+
/// The underlying XMLElement at the currently indexed level of XML.
111+
public var element: XMLElement? {
112+
get {
113+
switch self {
114+
case .Element(let elem):
115+
return elem
116+
default:
117+
return nil
118+
}
119+
}
120+
}
121+
122+
/// The underlying array of XMLElements at the currently indexed level of XML.
123+
public var all: [XMLIndexer] {
124+
get {
125+
switch self {
126+
case .List(let list):
127+
var xmlList = [XMLIndexer]()
128+
for elem in list {
129+
xmlList.append(XMLIndexer(elem))
130+
}
131+
return xmlList
132+
case .Element(let elem):
133+
return [XMLIndexer(elem)]
134+
default:
135+
return []
136+
}
137+
}
138+
}
139+
140+
/**
141+
Initializes the XMLIndexer
142+
143+
:param: _ should be an instance of XMLElement, but supports other values for error handling
144+
145+
:returns: instance of XMLIndexer
146+
*/
147+
public init(_ rawObject: AnyObject) {
148+
switch rawObject {
149+
case let value as XMLElement:
150+
self = .Element(value)
151+
default:
152+
self = .Error(NSError(domain: "SWXMLDomain", code: 1000, userInfo: nil))
153+
}
154+
}
155+
156+
/**
157+
Find an XML element at the current level by element name
158+
159+
:param: key The element name to index by
160+
161+
:returns: instance of XMLIndexer to match the element (or elements) found by key
162+
*/
163+
public subscript(key: String) -> XMLIndexer {
164+
get {
165+
let userInfo = [NSLocalizedDescriptionKey: "XML Element Error: Incorrect key [\"\(key)\"]"]
166+
switch self {
167+
case .Element(let elem):
168+
if let match = elem.elements[key] {
169+
if match.count == 1 {
170+
return .Element(match[0])
171+
}
172+
else {
173+
return .List(match)
174+
}
175+
}
176+
return .Error(NSError(domain: "SWXMLDomain", code: 1000, userInfo: userInfo))
177+
default:
178+
return .Error(NSError(domain: "SWXMLDomain", code: 1000, userInfo: userInfo))
179+
}
180+
}
181+
}
182+
183+
/**
184+
Find an XML element by index within a list of XML Elements at the current level
185+
186+
:param: index The 0-based index to index by
187+
188+
:returns: instance of XMLIndexer to match the element (or elements) found by key
189+
*/
190+
public subscript(index: Int) -> XMLIndexer {
191+
get {
192+
let userInfo = [NSLocalizedDescriptionKey: "XML Element Error: Incorrect index [\"\(index)\"]"]
193+
switch self {
194+
case .List(let list):
195+
if index <= list.count {
196+
return .Element(list[index])
197+
}
198+
return .Error(NSError(domain: "SWXMLDomain", code: 1000, userInfo: userInfo))
199+
case .Element(let elem):
200+
if index == 0 {
201+
return .Element(elem)
202+
}
203+
else {
204+
return .Error(NSError(domain: "SWXMLDomain", code: 1000, userInfo: userInfo))
205+
}
206+
default:
207+
return .Error(NSError(domain: "SWXMLDomain", code: 1000, userInfo: userInfo))
208+
}
209+
}
210+
}
211+
}
212+
213+
/// XMLIndexer extensions
214+
extension XMLIndexer: BooleanType {
215+
/// True if a valid XMLIndexer, false if an error type
216+
public var boolValue: Bool {
217+
get {
218+
switch self {
219+
case .Error:
220+
return false
221+
default:
222+
return true
223+
}
224+
}
225+
}
226+
}
227+
228+
/// Models an XML element, including name, text and attributes
229+
public class XMLElement {
230+
/// The name of the element
231+
public let name: String
232+
/// The inner text of the element, if it exists
233+
public var text: String?
234+
/// The attributes of the element
235+
public var attributes = [String:String]()
236+
237+
var elements = [String:[XMLElement]]()
238+
239+
/**
240+
Initialize an XMLElement instance
241+
242+
:param: name The name of the element to be initialized
243+
244+
:returns: a new instance of XMLElement
245+
*/
246+
init(name: String) {
247+
self.name = name
248+
}
249+
250+
/**
251+
Adds a new XMLElement underneath this instance of XMLElement
252+
253+
:param: name The name of the new element to be added
254+
:param: withAttributes The attributes dictionary for the element being added
255+
256+
:returns: The XMLElement that has now been added
257+
*/
258+
func addElement(name: String, withAttributes attributes: NSDictionary) -> XMLElement {
259+
let element = XMLElement(name: name)
260+
261+
if var group = elements[name] {
262+
group.append(element)
263+
elements[name] = group
264+
}
265+
else {
266+
elements[name] = [element]
267+
}
268+
269+
for (keyAny,valueAny) in attributes {
270+
let key = keyAny as String
271+
let value = valueAny as String
272+
element.attributes[key] = value
273+
}
274+
275+
return element
276+
}
277+
}

SWXMLHash/Extensions.swift

Lines changed: 0 additions & 35 deletions
This file was deleted.

SWXMLHash/Info.plist

Lines changed: 0 additions & 26 deletions
This file was deleted.

SWXMLHash/SWXMLHash.h

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)