0001    //
0002    //  SWXMLHash.swift
0003    //
0004    //  Copyright (c) 2014 David Mohundro
0005    //
0006    //  Permission is hereby granted, free of charge, to any person obtaining a copy
0007    //  of this software and associated documentation files (the "Software"), to deal
0008    //  in the Software without restriction, including without limitation the rights
0009    //  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0010    //  copies of the Software, and to permit persons to whom the Software is
0011    //  furnished to do so, subject to the following conditions:
0012    //
0013    //  The above copyright notice and this permission notice shall be included in
0014    //  all copies or substantial portions of the Software.
0015    //
0016    //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0017    //  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0018    //  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0019    //  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0020    //  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0021    //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0022    //  THE SOFTWARE.
0023    
0024    // swiftlint exceptions:
0025    // - Disabled file_length because there are a number of users that still pull the
0026    //   source down as is and it makes pulling the code into a project easier.
0027    
0028    // swiftlint:disable file_length
0029    
0030    import Foundation
0031    
0032    let rootElementName
SWXMLHash.swift:163
    var root = XMLElement(name: rootElementName)
SWXMLHash.swift:180
        root = XMLElement(name: rootElementName)
SWXMLHash.swift:247
    var root = XMLElement(name: rootElementName)
SWXMLHash.swift:586
            if elem.name == rootElementName {
= "SWXMLHash_Root_Element" 0033 0034 /// Parser options 0035 public class SWXMLHashOptions
SWXMLHash.swift:48
    let options: SWXMLHashOptions
SWXMLHash.swift:50
    private init(_ options: SWXMLHashOptions = SWXMLHashOptions()) {
SWXMLHash.swift:50
    private init(_ options: SWXMLHashOptions = SWXMLHashOptions()) {
SWXMLHash.swift:62
    class public func config(configAction: (SWXMLHashOptions) -> ()) -> SWXMLHash {
SWXMLHash.swift:63
        let opts = SWXMLHashOptions()
SWXMLHash.swift:152
    init(_ options: SWXMLHashOptions)
SWXMLHash.swift:158
    required init(_ options: SWXMLHashOptions) {
SWXMLHash.swift:169
    let options: SWXMLHashOptions
SWXMLHash.swift:242
    required init(_ options: SWXMLHashOptions) {
SWXMLHash.swift:249
    let options: SWXMLHashOptions
{ 0036 internal init
SWXMLHash.swift:50
    private init(_ options: SWXMLHashOptions = SWXMLHashOptions()) {
SWXMLHash.swift:63
        let opts = SWXMLHashOptions()
() {} 0037 0038 /// determines whether to parse the XML with lazy parsing or not 0039 public var shouldProcessLazily
SWXMLHash.swift:88
        let parser: SimpleXmlParser = options.shouldProcessLazily
SWXMLHash.swift:121
        return config { conf in conf.shouldProcessLazily = true }.parse(xml)
SWXMLHash.swift:131
        return config { conf in conf.shouldProcessLazily = true }.parse(data)
= false 0040 0041 /// determines whether to parse XML namespaces or not (forwards to 0042 /// `NSXMLParser.shouldProcessNamespaces`) 0043 public var shouldProcessNamespaces
SWXMLHash.swift:185
        parser.shouldProcessNamespaces = options.shouldProcessNamespaces
SWXMLHash.swift:259
        parser.shouldProcessNamespaces = options.shouldProcessNamespaces
= false 0044 } 0045 0046 /// Simple XML parser 0047 public class SWXMLHash
SWXMLHash.swift:62
    class public func config(configAction: (SWXMLHashOptions) -> ()) -> SWXMLHash {
SWXMLHash.swift:65
        return SWXMLHash(opts)
SWXMLHash.swift:101
        return SWXMLHash().parse(xml)
SWXMLHash.swift:111
        return SWXMLHash().parse(data)
{ 0048 let options
SWXMLHash.swift:51
        self.options = options
SWXMLHash.swift:88
        let parser: SimpleXmlParser = options.shouldProcessLazily
SWXMLHash.swift:89
            ? LazyXMLParser(options)
SWXMLHash.swift:90
            : XMLParser(options)
: SWXMLHashOptions 0049 0050 private init
SWXMLHash.swift:65
        return SWXMLHash(opts)
SWXMLHash.swift:101
        return SWXMLHash().parse(xml)
SWXMLHash.swift:111
        return SWXMLHash().parse(data)
(_ options: SWXMLHashOptions = SWXMLHashOptions()) { 0051 self.options = options 0052 } 0053 0054 /** 0055 Method to configure how parsing works. 0056 0057 - parameters: 0058 - configAction: a block that passes in an `SWXMLHashOptions` object with 0059 options to be set 0060 - returns: an `SWXMLHash` instance 0061 */ 0062 class public func config
SWXMLHash.swift:121
        return config { conf in conf.shouldProcessLazily = true }.parse(xml)
SWXMLHash.swift:131
        return config { conf in conf.shouldProcessLazily = true }.parse(data)
(configAction: (SWXMLHashOptions) -> ()) -> SWXMLHash { 0063 let opts = SWXMLHashOptions() 0064 configAction(opts) 0065 return SWXMLHash(opts) 0066 } 0067 0068 /** 0069 Begins parsing the passed in XML string. 0070 0071 - parameters: 0072 - xml: an XML string. __Note__ that this is not a URL but a 0073 string containing XML. 0074 - returns: an `XMLIndexer` instance that can be iterated over 0075 */ 0076 public func parse
SWXMLHash.swift:101
        return SWXMLHash().parse(xml)
SWXMLHash.swift:121
        return config { conf in conf.shouldProcessLazily = true }.parse(xml)
(xml: String) -> XMLIndexer { 0077 return parse((xml as NSString).dataUsingEncoding(NSUTF8StringEncoding)!) 0078 } 0079 0080 /** 0081 Begins parsing the passed in XML string. 0082 0083 - parameters: 0084 - data: an `NSData` instance containing XML 0085 - returns: an `XMLIndexer` instance that can be iterated over 0086 */ 0087 public func parse
SWXMLHash.swift:77
        return parse((xml as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
SWXMLHash.swift:111
        return SWXMLHash().parse(data)
SWXMLHash.swift:131
        return config { conf in conf.shouldProcessLazily = true }.parse(data)
(data: NSData) -> XMLIndexer { 0088 let parser: SimpleXmlParser = options.shouldProcessLazily 0089 ? LazyXMLParser(options) 0090 : XMLParser(options) 0091 return parser.parse(data) 0092 } 0093 0094 /** 0095 Method to parse XML passed in as a string. 0096 0097 - parameter xml: The XML to be parsed 0098 - returns: An XMLIndexer instance that is used to look up elements in the XML 0099 */ 0100 class public func parse(xml: String) -> XMLIndexer { 0101 return SWXMLHash().parse(xml) 0102 } 0103 0104 /** 0105 Method to parse XML passed in as an NSData instance. 0106 0107 - parameter data: The XML to be parsed 0108 - returns: An XMLIndexer instance that is used to look up elements in the XML 0109 */ 0110 class public func parse(data: NSData) -> XMLIndexer { 0111 return SWXMLHash().parse(data) 0112 } 0113 0114 /** 0115 Method to lazily parse XML passed in as a string. 0116 0117 - parameter xml: The XML to be parsed 0118 - returns: An XMLIndexer instance that is used to look up elements in the XML 0119 */ 0120 class public func lazy(xml: String) -> XMLIndexer { 0121 return config { conf in conf.shouldProcessLazily = true }.parse(xml) 0122 } 0123 0124 /** 0125 Method to lazily parse XML passed in as an NSData instance. 0126 0127 - parameter data: The XML to be parsed 0128 - returns: An XMLIndexer instance that is used to look up elements in the XML 0129 */ 0130 class public func lazy(data: NSData) -> XMLIndexer { 0131 return config { conf in conf.shouldProcessLazily = true }.parse(data) 0132 } 0133 } 0134 0135 struct Stack
SWXMLHash.swift:164
    var parentStack = Stack<XMLElement>()
SWXMLHash.swift:165
    var elementStack = Stack<String>()
SWXMLHash.swift:248
    var parentStack = Stack<XMLElement>()
<T
SWXMLHash.swift:136
    var items = [T]()
SWXMLHash.swift:137
    mutating func push(item: T) {
SWXMLHash.swift:140
    mutating func pop() -> T {
SWXMLHash.swift:146
    func top() -> T {
> { 0136 var items
SWXMLHash.swift:138
        items.append(item)
SWXMLHash.swift:141
        return items.removeLast()
SWXMLHash.swift:144
        items.removeAll(keepCapacity: false)
SWXMLHash.swift:147
        return items[items.count - 1]
SWXMLHash.swift:147
        return items[items.count - 1]
SWXMLHash.swift:232
        if elementStack.items.count > ops.count {
SWXMLHash.swift:233
            return elementStack.items.startsWith(ops.map { $0.key })
SWXMLHash.swift:235
            return ops.map { $0.key }.startsWith(elementStack.items)
= [T]() 0137 mutating func push
SWXMLHash.swift:181
        parentStack.push(root)
SWXMLHash.swift:196
        elementStack.push(elementName)
SWXMLHash.swift:202
        parentStack.push(currentNode)
SWXMLHash.swift:256
        parentStack.push(root)
SWXMLHash.swift:273
        parentStack.push(currentNode)
(item: T) { 0138 items.append(item) 0139 } 0140 mutating func pop
SWXMLHash.swift:222
        elementStack.pop()
SWXMLHash.swift:225
            parentStack.pop()
SWXMLHash.swift:287
        parentStack.pop()
() -> T { 0141 return items.removeLast() 0142 } 0143 mutating func removeAll
SWXMLHash.swift:179
        parentStack.removeAll()
SWXMLHash.swift:254
        parentStack.removeAll()
() { 0144 items.removeAll(keepCapacity: false) 0145 } 0146 func top
SWXMLHash.swift:201
        let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict)
SWXMLHash.swift:210
        let current = parentStack.top()
SWXMLHash.swift:272
        let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict)
SWXMLHash.swift:277
        let current = parentStack.top()
() -> T { 0147 return items[items.count - 1] 0148 } 0149 } 0150 0151 protocol SimpleXmlParser
SWXMLHash.swift:88
        let parser: SimpleXmlParser = options.shouldProcessLazily
SWXMLHash.swift:157
class LazyXMLParser: NSObject, SimpleXmlParser, NSXMLParserDelegate {
SWXMLHash.swift:241
class XMLParser: NSObject, SimpleXmlParser, NSXMLParserDelegate {
{ 0152 init(_ options: SWXMLHashOptions) 0153 func parse
SWXMLHash.swift:91
        return parser.parse(data)
(data: NSData) -> XMLIndexer 0154 } 0155 0156 /// The implementation of NSXMLParserDelegate and where the lazy parsing actually happens. 0157 class LazyXMLParser
SWXMLHash.swift:89
            ? LazyXMLParser(options)
SWXMLHash.swift:315
    let parser: LazyXMLParser
SWXMLHash.swift:317
    init(parser: LazyXMLParser) {
SWXMLHash.swift:447
        case let value as LazyXMLParser:
SWXMLHash.swift:463
    init(_ stream: LazyXMLParser) {
: NSObject, SimpleXmlParser, NSXMLParserDelegate { 0158 required init
SWXMLHash.swift:89
            ? LazyXMLParser(options)
(_ options: SWXMLHashOptions) { 0159 self.options = options 0160 super.init() 0161 } 0162 0163 var root
SWXMLHash.swift:180
        root = XMLElement(name: rootElementName)
SWXMLHash.swift:181
        parentStack.push(root)
SWXMLHash.swift:323
        let indexer = XMLIndexer(parser.root)
= XMLElement(name: rootElementName) 0164 var parentStack
SWXMLHash.swift:179
        parentStack.removeAll()
SWXMLHash.swift:181
        parentStack.push(root)
SWXMLHash.swift:201
        let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict)
SWXMLHash.swift:202
        parentStack.push(currentNode)
SWXMLHash.swift:210
        let current = parentStack.top()
SWXMLHash.swift:225
            parentStack.pop()
= Stack<XMLElement>() 0165 var elementStack
SWXMLHash.swift:196
        elementStack.push(elementName)
SWXMLHash.swift:222
        elementStack.pop()
SWXMLHash.swift:232
        if elementStack.items.count > ops.count {
SWXMLHash.swift:233
            return elementStack.items.startsWith(ops.map { $0.key })
SWXMLHash.swift:235
            return ops.map { $0.key }.startsWith(elementStack.items)
= Stack<String>() 0166 0167 var data
SWXMLHash.swift:172
        self.data = data
SWXMLHash.swift:184
        let parser = NSXMLParser(data: data!)
: NSData? 0168 var ops
SWXMLHash.swift:183
        self.ops = ops
SWXMLHash.swift:232
        if elementStack.items.count > ops.count {
SWXMLHash.swift:233
            return elementStack.items.startsWith(ops.map { $0.key })
SWXMLHash.swift:235
            return ops.map { $0.key }.startsWith(elementStack.items)
: [IndexOp] = [] 0169 let options
SWXMLHash.swift:159
        self.options = options
SWXMLHash.swift:185
        parser.shouldProcessNamespaces = options.shouldProcessNamespaces
: SWXMLHashOptions 0170 0171 func parse(data: NSData) -> XMLIndexer { 0172 self.data = data 0173 return XMLIndexer(self) 0174 } 0175 0176 func startParsing
SWXMLHash.swift:322
        parser.startParsing(ops)
(ops: [IndexOp]) { 0177 // clear any prior runs of parse... expected that this won't be necessary, 0178 // but you never know 0179 parentStack.removeAll() 0180 root = XMLElement(name: rootElementName) 0181 parentStack.push(root) 0182 0183 self.ops = ops 0184 let parser = NSXMLParser(data: data!) 0185 parser.shouldProcessNamespaces = options.shouldProcessNamespaces 0186 parser.delegate = self 0187 parser.parse() 0188 } 0189 0190 func parser(parser: NSXMLParser, 0191 didStartElement elementName: String, 0192 namespaceURI: String?, 0193 qualifiedName qName: String?, 0194 attributes attributeDict: [String: String]) { 0195 0196 elementStack.push(elementName) 0197 0198 if !onMatch() { 0199 return 0200 } 0201 let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict) 0202 parentStack.push(currentNode) 0203 } 0204 0205 func parser(parser: NSXMLParser, foundCharacters string: String) { 0206 if !onMatch() { 0207 return 0208 } 0209 0210 let current = parentStack.top() 0211 0212 current.addText(string) 0213 } 0214 0215 func parser(parser: NSXMLParser, 0216 didEndElement elementName: String, 0217 namespaceURI: String?, 0218 qualifiedName qName: String?) { 0219 0220 let match = onMatch() 0221 0222 elementStack.pop() 0223 0224 if match { 0225 parentStack.pop() 0226 } 0227 } 0228 0229 func onMatch
SWXMLHash.swift:198
        if !onMatch() {
SWXMLHash.swift:206
        if !onMatch() {
SWXMLHash.swift:220
        let match = onMatch()
() -> Bool { 0230 // we typically want to compare against the elementStack to see if it matches ops, *but* 0231 // if we're on the first element, we'll instead compare the other direction. 0232 if elementStack.items.count > ops.count { 0233 return elementStack.items.startsWith(ops.map { $0.key }) 0234 } else { 0235 return ops.map { $0.key }.startsWith(elementStack.items) 0236 } 0237 } 0238 } 0239 0240 /// The implementation of NSXMLParserDelegate and where the parsing actually happens. 0241 class XMLParser
SWXMLHash.swift:90
            : XMLParser(options)
: NSObject, SimpleXmlParser, NSXMLParserDelegate { 0242 required init
SWXMLHash.swift:90
            : XMLParser(options)
(_ options: SWXMLHashOptions) { 0243 self.options = options 0244 super.init() 0245 } 0246 0247 var root
SWXMLHash.swift:256
        parentStack.push(root)
SWXMLHash.swift:263
        return XMLIndexer(root)
= XMLElement(name: rootElementName) 0248 var parentStack
SWXMLHash.swift:254
        parentStack.removeAll()
SWXMLHash.swift:256
        parentStack.push(root)
SWXMLHash.swift:272
        let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict)
SWXMLHash.swift:273
        parentStack.push(currentNode)
SWXMLHash.swift:277
        let current = parentStack.top()
SWXMLHash.swift:287
        parentStack.pop()
= Stack<XMLElement>() 0249 let options
SWXMLHash.swift:243
        self.options = options
SWXMLHash.swift:259
        parser.shouldProcessNamespaces = options.shouldProcessNamespaces
: SWXMLHashOptions 0250 0251 func parse(data: NSData) -> XMLIndexer { 0252 // clear any prior runs of parse... expected that this won't be necessary, 0253 // but you never know 0254 parentStack.removeAll() 0255 0256 parentStack.push(root) 0257 0258 let parser = NSXMLParser(data: data) 0259 parser.shouldProcessNamespaces = options.shouldProcessNamespaces 0260 parser.delegate = self 0261 parser.parse() 0262 0263 return XMLIndexer(root) 0264 } 0265 0266 func parser(parser: NSXMLParser, 0267 didStartElement elementName: String, 0268 namespaceURI: String?, 0269 qualifiedName qName: String?, 0270 attributes attributeDict: [String: String]) { 0271 0272 let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict) 0273 parentStack.push(currentNode) 0274 } 0275 0276 func parser(parser: NSXMLParser, foundCharacters string: String) { 0277 let current = parentStack.top() 0278 0279 current.addText(string) 0280 } 0281 0282 func parser(parser: NSXMLParser, 0283 didEndElement elementName: String, 0284 namespaceURI: String?, 0285 qualifiedName qName: String?) { 0286 0287 parentStack.pop() 0288 } 0289 } 0290 0291 /// Represents an indexed operation against a lazily parsed `XMLIndexer` 0292 public class IndexOp
SWXMLHash.swift:168
    var ops: [IndexOp] = []
SWXMLHash.swift:176
    func startParsing(ops: [IndexOp]) {
SWXMLHash.swift:313
    var ops: [IndexOp] = []
SWXMLHash.swift:477
            let op = IndexOp(key)
{ 0293 var index
SWXMLHash.swift:298
        self.index = -1
SWXMLHash.swift:302
        if index >= 0 {
SWXMLHash.swift:303
            return key + " " + index.description
SWXMLHash.swift:327
            if op.index >= 0 {
SWXMLHash.swift:328
                childIndex = childIndex[op.index]
SWXMLHash.swift:521
            opStream.ops[opStream.ops.count - 1].index = index
: Int 0294 let key
SWXMLHash.swift:233
            return elementStack.items.startsWith(ops.map { $0.key })
SWXMLHash.swift:235
            return ops.map { $0.key }.startsWith(elementStack.items)
SWXMLHash.swift:297
        self.key = key
SWXMLHash.swift:303
            return key + " " + index.description
SWXMLHash.swift:306
        return key
SWXMLHash.swift:326
            childIndex = childIndex[op.key]
: String 0295 0296 init
SWXMLHash.swift:477
            let op = IndexOp(key)
(_ key: String) { 0297 self.key = key 0298 self.index = -1 0299 } 0300 0301 func toString
SWXMLHash.swift:338
            s += "[" + op.toString() + "]"
() -> String { 0302 if index >= 0 { 0303 return key + " " + index.description 0304 } 0305 0306 return key 0307 } 0308 } 0309 0310 /// Represents a collection of `IndexOp` instances. Provides a means of iterating them 0311 /// to find a match in a lazily parsed `XMLIndexer` instance. 0312 public class IndexOps
SWXMLHash.swift:348
    case Stream(IndexOps)
SWXMLHash.swift:448
            self = .Stream(IndexOps(parser: value))
SWXMLHash.swift:464
        self = .Stream(IndexOps(parser: stream))
{ 0313 var ops
SWXMLHash.swift:322
        parser.startParsing(ops)
SWXMLHash.swift:325
        for op in ops {
SWXMLHash.swift:331
        ops.removeAll(keepCapacity: false)
SWXMLHash.swift:337
        for op in ops {
SWXMLHash.swift:478
            opStream.ops.append(op)
SWXMLHash.swift:521
            opStream.ops[opStream.ops.count - 1].index = index
SWXMLHash.swift:521
            opStream.ops[opStream.ops.count - 1].index = index
: [IndexOp] = [] 0314 0315 let parser
SWXMLHash.swift:318
        self.parser = parser
SWXMLHash.swift:322
        parser.startParsing(ops)
SWXMLHash.swift:323
        let indexer = XMLIndexer(parser.root)
: LazyXMLParser 0316 0317 init
SWXMLHash.swift:448
            self = .Stream(IndexOps(parser: value))
SWXMLHash.swift:464
        self = .Stream(IndexOps(parser: stream))
(parser: LazyXMLParser) { 0318 self.parser = parser 0319 } 0320 0321 func findElements
SWXMLHash.swift:367
            let list = ops.findElements()
SWXMLHash.swift:386
            let list = ops.findElements()
SWXMLHash.swift:417
            let match = opStream.findElements()
() -> XMLIndexer { 0322 parser.startParsing(ops) 0323 let indexer = XMLIndexer(parser.root) 0324 var childIndex = indexer 0325 for op in ops { 0326 childIndex = childIndex[op.key] 0327 if op.index >= 0 { 0328 childIndex = childIndex[op.index] 0329 } 0330 } 0331 ops.removeAll(keepCapacity: false) 0332 return childIndex 0333 } 0334 0335 func stringify
SWXMLHash.swift:416
            opStream.stringify()
() -> String { 0336 var s = "" 0337 for op in ops { 0338 s += "[" + op.toString() + "]" 0339 } 0340 return s 0341 } 0342 } 0343 0344 /// Returned from SWXMLHash, allows easy element lookup into XML data. 0345 public enum XMLIndexer
SWXMLHash.swift:76
    public func parse(xml: String) -> XMLIndexer {
SWXMLHash.swift:87
    public func parse(data: NSData) -> XMLIndexer {
SWXMLHash.swift:100
    class public func parse(xml: String) -> XMLIndexer {
SWXMLHash.swift:110
    class public func parse(data: NSData) -> XMLIndexer {
SWXMLHash.swift:120
    class public func lazy(xml: String) -> XMLIndexer {
SWXMLHash.swift:130
    class public func lazy(data: NSData) -> XMLIndexer {
SWXMLHash.swift:153
    func parse(data: NSData) -> XMLIndexer
SWXMLHash.swift:171
    func parse(data: NSData) -> XMLIndexer {
SWXMLHash.swift:173
        return XMLIndexer(self)
SWXMLHash.swift:251
    func parse(data: NSData) -> XMLIndexer {
SWXMLHash.swift:263
        return XMLIndexer(root)
SWXMLHash.swift:321
    func findElements() -> XMLIndexer {
SWXMLHash.swift:323
        let indexer = XMLIndexer(parser.root)
SWXMLHash.swift:378
            var xmlList = [XMLIndexer]()
SWXMLHash.swift:380
                xmlList.append(XMLIndexer(elem))
SWXMLHash.swift:384
            return [XMLIndexer(elem)]
SWXMLHash.swift:375
    public var all: [XMLIndexer] {
SWXMLHash.swift:395
        var list = [XMLIndexer]()
SWXMLHash.swift:398
                list.append(XMLIndexer(elem))
SWXMLHash.swift:394
    public var children: [XMLIndexer] {
SWXMLHash.swift:413
    public func withAttr(attr: String, _ value: String) throws -> XMLIndexer {
SWXMLHash.swift:474
    public func byKey(key: String) throws -> XMLIndexer {
SWXMLHash.swift:518
    public func byIndex(index: Int) throws -> XMLIndexer {
SWXMLHash.swift:554
    typealias GeneratorType = XMLIndexer
SWXMLHash.swift:561
    public func generate() -> IndexingGenerator<[XMLIndexer]> {
SWXMLHash.swift:567
extension XMLIndexer: BooleanType {
SWXMLHash.swift:579
extension XMLIndexer: CustomStringConvertible {
SWXMLHash.swift:597
extension XMLIndexer.Error: CustomStringConvertible {
: SequenceType { 0346 case Element
SWXMLHash.swift:364
        case .Element(let elem):
SWXMLHash.swift:383
        case .Element(let elem):
SWXMLHash.swift:421
                return .Element(elem)
SWXMLHash.swift:424
        case .Element(let elem):
SWXMLHash.swift:427
                    return .Element(elem)
SWXMLHash.swift:446
            self = .Element(value)
SWXMLHash.swift:460
        self = .Element(elem)
SWXMLHash.swift:480
        case .Element(let elem):
SWXMLHash.swift:484
                    return .Element(match[0])
SWXMLHash.swift:525
                return .Element(list[index])
SWXMLHash.swift:528
        case .Element(let elem):
SWXMLHash.swift:530
                return .Element(elem)
SWXMLHash.swift:585
        case .Element(let elem):
(XMLElement) 0347 case List
SWXMLHash.swift:377
        case .List(let list):
SWXMLHash.swift:419
        case .List(let list):
SWXMLHash.swift:486
                    return .List(match)
SWXMLHash.swift:523
        case .List(let list):
SWXMLHash.swift:583
        case .List(let list):
([XMLElement]) 0348 case Stream
SWXMLHash.swift:366
        case .Stream(let ops):
SWXMLHash.swift:385
        case .Stream(let ops):
SWXMLHash.swift:415
        case .Stream(let opStream):
SWXMLHash.swift:448
            self = .Stream(IndexOps(parser: value))
SWXMLHash.swift:464
        self = .Stream(IndexOps(parser: stream))
SWXMLHash.swift:476
        case .Stream(let opStream):
SWXMLHash.swift:479
            return .Stream(opStream)
SWXMLHash.swift:520
        case .Stream(let opStream):
SWXMLHash.swift:522
            return .Stream(opStream)
(IndexOps) 0349 case XMLError
SWXMLHash.swift:505
            return .XMLError(error)
SWXMLHash.swift:507
            return .XMLError(.Key(key: key))
SWXMLHash.swift:527
            return .XMLError(.Index(idx: index))
SWXMLHash.swift:534
            return .XMLError(.Index(idx: index))
SWXMLHash.swift:548
            return .XMLError(error)
SWXMLHash.swift:550
            return .XMLError(.Index(idx: index))
SWXMLHash.swift:571
        case .XMLError:
(Error) 0350 0351 /// Error type that is thrown when an indexing or parsing operation fails. 0352 public enum Error
SWXMLHash.swift:349
    case XMLError(Error)
SWXMLHash.swift:423
            throw Error.AttributeValue(attr: attr, value: value)
SWXMLHash.swift:429
                throw Error.AttributeValue(attr: attr, value: value)
SWXMLHash.swift:433
            throw Error.Attribute(attr: attr)
SWXMLHash.swift:450
            throw Error.Init(instance: rawObject)
SWXMLHash.swift:491
            throw Error.Key(key: key)
SWXMLHash.swift:504
        } catch let error as Error {
SWXMLHash.swift:547
        } catch let error as Error {
SWXMLHash.swift:597
extension XMLIndexer.Error: CustomStringConvertible {
: ErrorType { 0353 case Attribute
SWXMLHash.swift:433
            throw Error.Attribute(attr: attr)
SWXMLHash.swift:601
        case .Attribute(let attr):
(attr: String) 0354 case AttributeValue
SWXMLHash.swift:423
            throw Error.AttributeValue(attr: attr, value: value)
SWXMLHash.swift:429
                throw Error.AttributeValue(attr: attr, value: value)
SWXMLHash.swift:603
        case .AttributeValue(let attr, let value):
(attr: String, value: String) 0355 case Key
SWXMLHash.swift:491
            throw Error.Key(key: key)
SWXMLHash.swift:507
            return .XMLError(.Key(key: key))
SWXMLHash.swift:605
        case .Key(let key):
(key: String) 0356 case Index
SWXMLHash.swift:527
            return .XMLError(.Index(idx: index))
SWXMLHash.swift:534
            return .XMLError(.Index(idx: index))
SWXMLHash.swift:550
            return .XMLError(.Index(idx: index))
SWXMLHash.swift:607
        case .Index(let index):
(idx: Int) 0357 case Init
SWXMLHash.swift:450
            throw Error.Init(instance: rawObject)
SWXMLHash.swift:609
        case .Init(let instance):
(instance: AnyObject) 0358 case Error
SWXMLHash.swift:611
        case .Error:
0359 } 0360 0361 /// The underlying XMLElement at the currently indexed level of XML. 0362 public var element
SWXMLHash.swift:368
            return list.element
SWXMLHash.swift:396
        for elem in all.map({ $0.element! }).flatMap({ $0 }) {
: XMLElement? { 0363 switch self { 0364 case .Element(let elem): 0365 return elem 0366 case .Stream(let ops): 0367 let list = ops.findElements() 0368 return list.element 0369 default: 0370 return nil 0371 } 0372 } 0373 0374 /// All elements at the currently indexed level 0375 public var all
SWXMLHash.swift:387
            return list.all
SWXMLHash.swift:396
        for elem in all.map({ $0.element! }).flatMap({ $0 }) {
SWXMLHash.swift:562
        return all.generate()
: [XMLIndexer] { 0376 switch self { 0377 case .List(let list): 0378 var xmlList = [XMLIndexer]() 0379 for elem in list { 0380 xmlList.append(XMLIndexer(elem)) 0381 } 0382 return xmlList 0383 case .Element(let elem): 0384 return [XMLIndexer(elem)] 0385 case .Stream(let ops): 0386 let list = ops.findElements() 0387 return list.all 0388 default: 0389 return [] 0390 } 0391 } 0392 0393 /// All child elements from the currently indexed level 0394 public var children: [XMLIndexer] { 0395 var list = [XMLIndexer]() 0396 for elem in all.map({ $0.element! }).flatMap({ $0 }) { 0397 for elem in elem.xmlChildren { 0398 list.append(XMLIndexer(elem)) 0399 } 0400 } 0401 return list 0402 } 0403 0404 /** 0405 Allows for element lookup by matching attribute values. 0406 0407 - parameters: 0408 - attr: should the name of the attribute to match on 0409 - value: should be the value of the attribute to match on 0410 - throws: an XMLIndexer.XMLError if an element with the specified attribute isn't found 0411 - returns: instance of XMLIndexer 0412 */ 0413 public func withAttr
SWXMLHash.swift:418
            return try match.withAttr(attr, value)
(attr: String, _ value: String) throws -> XMLIndexer { 0414 switch self { 0415 case .Stream(let opStream): 0416 opStream.stringify() 0417 let match = opStream.findElements() 0418 return try match.withAttr(attr, value) 0419 case .List(let list): 0420 if let elem = list.filter({$0.attributes[attr] == value}).first { 0421 return .Element(elem) 0422 } 0423 throw Error.AttributeValue(attr: attr, value: value) 0424 case .Element(let elem): 0425 if let attr = elem.attributes[attr] { 0426 if attr == value { 0427 return .Element(elem) 0428 } 0429 throw Error.AttributeValue(attr: attr, value: value) 0430 } 0431 fallthrough 0432 default: 0433 throw Error.Attribute(attr: attr) 0434 } 0435 } 0436 0437 /** 0438 Initializes the XMLIndexer 0439 0440 - parameter _: should be an instance of XMLElement, but supports other values for error handling 0441 - throws: an Error if the object passed in isn't an XMLElement or LaxyXMLParser 0442 */ 0443 public init(_ rawObject: AnyObject) throws { 0444 switch rawObject { 0445 case let value as XMLElement: 0446 self = .Element(value) 0447 case let value as LazyXMLParser: 0448 self = .Stream(IndexOps(parser: value)) 0449 default: 0450 throw Error.Init(instance: rawObject) 0451 } 0452 } 0453 0454 /** 0455 Initializes the XMLIndexer 0456 0457 - parameter _: an instance of XMLElement 0458 */ 0459 public init
SWXMLHash.swift:263
        return XMLIndexer(root)
SWXMLHash.swift:323
        let indexer = XMLIndexer(parser.root)
SWXMLHash.swift:380
                xmlList.append(XMLIndexer(elem))
SWXMLHash.swift:384
            return [XMLIndexer(elem)]
SWXMLHash.swift:398
                list.append(XMLIndexer(elem))
(_ elem: XMLElement) { 0460 self = .Element(elem) 0461 } 0462 0463 init
SWXMLHash.swift:173
        return XMLIndexer(self)
(_ stream: LazyXMLParser) { 0464 self = .Stream(IndexOps(parser: stream)) 0465 } 0466 0467 /** 0468 Find an XML element at the current level by element name 0469 0470 - parameter key: The element name to index by 0471 - returns: instance of XMLIndexer to match the element (or elements) found by key 0472 - throws: Throws an XMLIndexerError.Key if no element was found 0473 */ 0474 public func byKey
SWXMLHash.swift:503
           return try self.byKey(key)
(key: String) throws -> XMLIndexer { 0475 switch self { 0476 case .Stream(let opStream): 0477 let op = IndexOp(key) 0478 opStream.ops.append(op) 0479 return .Stream(opStream) 0480 case .Element(let elem): 0481 let match = elem.xmlChildren.filter({ $0.name == key }) 0482 if !match.isEmpty { 0483 if match.count == 1 { 0484 return .Element(match[0]) 0485 } else { 0486 return .List(match) 0487 } 0488 } 0489 fallthrough 0490 default: 0491 throw Error.Key(key: key) 0492 } 0493 } 0494 0495 /** 0496 Find an XML element at the current level by element name 0497 0498 - parameter key: The element name to index by 0499 - returns: instance of XMLIndexer to match the element (or elements) found by 0500 */ 0501 public subscript
SWXMLHash.swift:326
            childIndex = childIndex[op.key]
(key: String) -> XMLIndexer { 0502 do { 0503 return try self.byKey(key) 0504 } catch let error as Error { 0505 return .XMLError(error) 0506 } catch { 0507 return .XMLError(.Key(key: key)) 0508 } 0509 } 0510 0511 /** 0512 Find an XML element by index within a list of XML Elements at the current level 0513 0514 - parameter index: The 0-based index to index by 0515 - throws: XMLIndexer.XMLError if the index isn't found 0516 - returns: instance of XMLIndexer to match the element (or elements) found by index 0517 */ 0518 public func byIndex
SWXMLHash.swift:546
            return try byIndex(index)
(index: Int) throws -> XMLIndexer { 0519 switch self { 0520 case .Stream(let opStream): 0521 opStream.ops[opStream.ops.count - 1].index = index 0522 return .Stream(opStream) 0523 case .List(let list): 0524 if index <= list.count { 0525 return .Element(list[index]) 0526 } 0527 return .XMLError(.Index(idx: index)) 0528 case .Element(let elem): 0529 if index == 0 { 0530 return .Element(elem) 0531 } 0532 fallthrough 0533 default: 0534 return .XMLError(.Index(idx: index)) 0535 } 0536 } 0537 0538 /** 0539 Find an XML element by index 0540 0541 - parameter index: The 0-based index to index by 0542 - returns: instance of XMLIndexer to match the element (or elements) found by index 0543 */ 0544 public subscript
SWXMLHash.swift:328
                childIndex = childIndex[op.index]
(index: Int) -> XMLIndexer { 0545 do { 0546 return try byIndex(index) 0547 } catch let error as Error { 0548 return .XMLError(error) 0549 } catch { 0550 return .XMLError(.Index(idx: index)) 0551 } 0552 } 0553 0554 typealias GeneratorType = XMLIndexer 0555 0556 /** 0557 Method to iterate (for-in) over the `all` collection 0558 0559 - returns: an array of `XMLIndexer` instances 0560 */ 0561 public func generate() -> IndexingGenerator<[XMLIndexer]> { 0562 return all.generate() 0563 } 0564 } 0565 0566 /// XMLIndexer extensions 0567 extension XMLIndexer: BooleanType { 0568 /// True if a valid XMLIndexer, false if an error type 0569 public var boolValue: Bool { 0570 switch self { 0571 case .XMLError: 0572 return false 0573 default: 0574 return true 0575 } 0576 } 0577 } 0578 0579 extension XMLIndexer: CustomStringConvertible { 0580 /// The XML representation of the XMLIndexer at the current level 0581 public var description: String { 0582 switch self { 0583 case .List(let list): 0584 return list.map { $0.description }.joinWithSeparator("") 0585 case .Element(let elem): 0586 if elem.name == rootElementName { 0587 return elem.children.map { $0.description }.joinWithSeparator("") 0588 } 0589 0590 return elem.description 0591 default: 0592 return "" 0593 } 0594 } 0595 } 0596 0597 extension XMLIndexer.Error: CustomStringConvertible { 0598 /// The description for the `XMLIndexer.Error`. 0599 public var description: String { 0600 switch self { 0601 case .Attribute(let attr): 0602 return "XML Attribute Error: Missing attribute [\"\(attr)\"]" 0603 case .AttributeValue(let attr, let value): 0604 return "XML Attribute Error: Missing attribute [\"\(attr)\"] with value [\"\(value)\"]" 0605 case .Key(let key): 0606 return "XML Element Error: Incorrect key [\"\(key)\"]" 0607 case .Index(let index): 0608 return "XML Element Error: Incorrect index [\"\(index)\"]" 0609 case .Init(let instance): 0610 return "XML Indexer Error: initialization with Object [\"\(instance)\"]" 0611 case .Error: 0612 return "Unknown Error" 0613 } 0614 } 0615 } 0616 0617 /// Models content for an XML doc, whether it is text or XML 0618 public protocol XMLContent
SWXMLHash.swift:622
public class TextElement: XMLContent {
SWXMLHash.swift:630
public class XMLElement: XMLContent {
SWXMLHash.swift:644
    var children = [XMLContent]()
: CustomStringConvertible { 0619 } 0620 0621 /// Models a text element 0622 public class TextElement
SWXMLHash.swift:639
            .map({ $0 as? TextElement })
SWXMLHash.swift:689
        let elem = TextElement(text: text)
SWXMLHash.swift:695
extension TextElement: CustomStringConvertible {
: XMLContent { 0623 public let text
SWXMLHash.swift:625
        self.text = text
SWXMLHash.swift:641
            .reduce("", combine: { $0 + $1!.text })
SWXMLHash.swift:698
        return text
: String 0624 init
SWXMLHash.swift:689
        let elem = TextElement(text: text)
(text: String) { 0625 self.text = text 0626 } 0627 } 0628 0629 /// Models an XML element, including name, text and attributes 0630 public class XMLElement
SWXMLHash.swift:163
    var root = XMLElement(name: rootElementName)
SWXMLHash.swift:164
    var parentStack = Stack<XMLElement>()
SWXMLHash.swift:180
        root = XMLElement(name: rootElementName)
SWXMLHash.swift:247
    var root = XMLElement(name: rootElementName)
SWXMLHash.swift:248
    var parentStack = Stack<XMLElement>()
SWXMLHash.swift:346
    case Element(XMLElement)
SWXMLHash.swift:347
    case List([XMLElement])
SWXMLHash.swift:362
    public var element: XMLElement? {
SWXMLHash.swift:445
        case let value as XMLElement:
SWXMLHash.swift:459
    public init(_ elem: XMLElement) {
SWXMLHash.swift:649
        return children.map { $0 as? XMLElement }.flatMap { $0 }
SWXMLHash.swift:648
    var xmlChildren: [XMLElement] {
SWXMLHash.swift:672
    func addElement(name: String, withAttributes attributes: NSDictionary) -> XMLElement {
SWXMLHash.swift:673
        let element = XMLElement(name: name, index: count)
SWXMLHash.swift:702
extension XMLElement: CustomStringConvertible {
: XMLContent { 0631 /// The name of the element 0632 public let name
SWXMLHash.swift:481
            let match = elem.xmlChildren.filter({ $0.name == key })
SWXMLHash.swift:586
            if elem.name == rootElementName {
SWXMLHash.swift:660
        self.name = name
SWXMLHash.swift:719
            xmlReturn.append("<\(name)\(attributesString)>")
SWXMLHash.swift:723
            xmlReturn.append("</\(name)>")
SWXMLHash.swift:728
            return "<\(name)\(attributesString)>\(text!)</\(name)>"
SWXMLHash.swift:728
            return "<\(name)\(attributesString)>\(text!)</\(name)>"
SWXMLHash.swift:730
            return "<\(name)\(attributesString)/>"
: String 0633 /// The attributes of the element 0634 public var attributes
SWXMLHash.swift:420
            if let elem = list.filter({$0.attributes[attr] == value}).first {
SWXMLHash.swift:425
            if let attr = elem.attributes[attr] {
SWXMLHash.swift:681
                element.attributes[key] = value
SWXMLHash.swift:706
        if !attributes.isEmpty {
SWXMLHash.swift:707
            for (key, val) in attributes {
= [String:String]() 0635 0636 /// The inner text of the element, if it exists 0637 public var text
SWXMLHash.swift:727
        if text != nil {
SWXMLHash.swift:728
            return "<\(name)\(attributesString)>\(text!)</\(name)>"
: String? { 0638 return children 0639 .map({ $0 as? TextElement }) 0640 .flatMap({ $0 }) 0641 .reduce("", combine: { $0 + $1!.text }) 0642 } 0643 0644 var children
SWXMLHash.swift:587
                return elem.children.map { $0.description }.joinWithSeparator("")
SWXMLHash.swift:638
        return children
SWXMLHash.swift:649
        return children.map { $0 as? XMLElement }.flatMap { $0 }
SWXMLHash.swift:676
        children.append(element)
SWXMLHash.swift:691
        children.append(elem)
SWXMLHash.swift:717
        if !children.isEmpty {
SWXMLHash.swift:720
            for child in children {
= [XMLContent]() 0645 var count
SWXMLHash.swift:673
        let element = XMLElement(name: name, index: count)
SWXMLHash.swift:674
        count += 1
: Int = 0 0646 var index
SWXMLHash.swift:661
        self.index = index
: Int 0647 0648 var xmlChildren
SWXMLHash.swift:397
            for elem in elem.xmlChildren {
SWXMLHash.swift:481
            let match = elem.xmlChildren.filter({ $0.name == key })
: [XMLElement] { 0649 return children.map { $0 as? XMLElement }.flatMap { $0 } 0650 } 0651 0652 /** 0653 Initialize an XMLElement instance 0654 0655 - parameters: 0656 - name: The name of the element to be initialized 0657 - index: The index of the element to be initialized 0658 */ 0659 init
SWXMLHash.swift:163
    var root = XMLElement(name: rootElementName)
SWXMLHash.swift:180
        root = XMLElement(name: rootElementName)
SWXMLHash.swift:247
    var root = XMLElement(name: rootElementName)
SWXMLHash.swift:673
        let element = XMLElement(name: name, index: count)
(name: String, index: Int = 0) { 0660 self.name = name 0661 self.index = index 0662 } 0663 0664 /** 0665 Adds a new XMLElement underneath this instance of XMLElement 0666 0667 - parameters: 0668 - name: The name of the new element to be added 0669 - withAttributes: The attributes dictionary for the element being added 0670 - returns: The XMLElement that has now been added 0671 */ 0672 func addElement
SWXMLHash.swift:201
        let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict)
SWXMLHash.swift:272
        let currentNode = parentStack.top().addElement(elementName, withAttributes: attributeDict)
(name: String, withAttributes attributes: NSDictionary) -> XMLElement { 0673 let element = XMLElement(name: name, index: count) 0674 count += 1 0675 0676 children.append(element) 0677 0678 for (keyAny, valueAny) in attributes { 0679 if let key = keyAny as? String, 0680 let value = valueAny as? String { 0681 element.attributes[key] = value 0682 } 0683 } 0684 0685 return element 0686 } 0687 0688 func addText
SWXMLHash.swift:212
        current.addText(string)
SWXMLHash.swift:279
        current.addText(string)
(text: String) { 0689 let elem = TextElement(text: text) 0690 0691 children.append(elem) 0692 } 0693 } 0694 0695 extension TextElement: CustomStringConvertible { 0696 /// The text value for a `TextElement` instance. 0697 public var description: String { 0698 return text 0699 } 0700 } 0701 0702 extension XMLElement: CustomStringConvertible { 0703 /// The tag, attributes and content for a `XMLElement` instance (<elem id="foo">content</elem>) 0704 public var description
SWXMLHash.swift:584
            return list.map { $0.description }.joinWithSeparator("")
SWXMLHash.swift:590
            return elem.description
: String { 0705 var attributesStringList = [String]() 0706 if !attributes.isEmpty { 0707 for (key, val) in attributes { 0708 attributesStringList.append("\(key)=\"\(val)\"") 0709 } 0710 } 0711 0712 var attributesString = attributesStringList.joinWithSeparator(" ") 0713 if !attributesString.isEmpty { 0714 attributesString = " " + attributesString 0715 } 0716 0717 if !children.isEmpty { 0718 var xmlReturn = [String]() 0719 xmlReturn.append("<\(name)\(attributesString)>") 0720 for child in children { 0721 xmlReturn.append(child.description) 0722 } 0723 xmlReturn.append("</\(name)>") 0724 return xmlReturn.joinWithSeparator("") 0725 } 0726 0727 if text != nil { 0728 return "<\(name)\(attributesString)>\(text!)</\(name)>" 0729 } else { 0730 return "<\(name)\(attributesString)/>" 0731 } 0732 } 0733 } 0734