### Iterate Over All Elements at Level Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Use the `all` property to get a collection of all elements at the current level, allowing iteration over them. This example maps and joins the text content of 'genre' elements. ```swift ", ".join(xml["root"]["catalog"]["book"].all.map { elem in elem["genre"].element!.text! }) ``` -------------------------------- ### Configure XML Parsing Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Use the `configure` method to set parsing options like lazy loading, namespace processing, case sensitivity, encoding, user info, and error detection. This example shows a basic configuration block. ```swift let xml = XMLHash.config { config in // set any config options here }.parse(xmlToParse) ``` -------------------------------- ### Define XML structure for custom deserialization Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Example XML input used for demonstrating custom Date deserialization. ```xml Monday, 23 January 2016 12:01:12 111 ``` -------------------------------- ### Loop Through All Elements at Level Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Iterate directly over the collection provided by the `all` property to process each element at the current level. This example prints the text of the 'genre' element for each book. ```swift for elem in xml["root"]["catalog"]["book"].all { print(elem["genre"].element!.text!) } ``` -------------------------------- ### Lazy Parsing Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Provides examples for performing lazy parsing of XML, which can improve performance for large files. ```APIDOC ## Lazy Parsing ### Description Performs lazy parsing of an XML string, which avoids loading the entire document into memory and can be preferable for performance reasons with large XML files. ### Method `lazy` or `config { config.shouldProcessLazily = true }.parse()` ### Endpoint N/A (Method on `XMLHash` struct) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body - **xmlToParse** (String) - Required - The XML string to be parsed lazily. ### Request Example ```swift // Using the config method let xml = XMLHash.config { config in config.shouldProcessLazily = true }.parse(xmlToParse) // Using the direct lazy method let xml = XMLHash.lazy(xmlToParse) ``` ### Response - **XMLIndexer** - The lazily parsed XML structure. ``` -------------------------------- ### Trigger deserialization error Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Example of a call that fails due to missing built-in deserializer for Date. ```swift let dateValue: Date = try! xml["root"]["date"].value() ``` -------------------------------- ### Deserialize XML into Custom Swift Objects Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Implement the XMLObjectDeserialization protocol to convert XML nodes into custom Swift structs or classes. This example shows deserializing book data, including nested elements and attributes. ```swift struct Book: XMLObjectDeserialization { let title: String let price: Double let year: Int let amount: Int? let isbn: Int let category: [String] static func deserialize(_ node: XMLIndexer) throws -> Book { return try Book( title: node["title"].value(), price: node["price"].value(), year: node["year"].value(), amount: node["amount"].value(), isbn: node.value(ofAttribute: "isbn"), category : node["categories"]["category"].value() ) } } ``` -------------------------------- ### Add SWXMLHash as a CocoaPods Dependency Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md To install SWXMLHash using CocoaPods, add the pod to your Podfile. Ensure your platform is set to iOS 10.0 or higher and use frameworks. ```ruby platform :ios, '10.0' use_frameworks! target 'YOUR_TARGET_NAME' do pod 'SWXMLHash', '~> 7.0.0' end ``` -------------------------------- ### Filter XML Elements by Attribute and Index Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Use filterAll and filterChildren to select specific XML elements based on attribute values and their index within the parent. This example filters for a book with id 'bk102' and then selects its children within a specific index range. ```swift let subIndexer = xml!["root"]["catalog"]["book"] .filterAll { elem, _ in elem.attribute(by: "id")!.text == "bk102" } .filterChildren { _, index in index >= 1 && index <= 3 } print(subIndexer.children[0].element?.text) ``` -------------------------------- ### Import FoundationNetworking for Web Contexts Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md To use SWXMLHash in a web context such as Vapor, include conditional import logic for `FoundationNetworking` if it can be imported. ```swift #if canImport(FoundationNetworking) import FoundationNetworking #endif ``` -------------------------------- ### Basic Parsing Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Demonstrates the basic initialization and parsing of an XML string. ```APIDOC ## Basic Parsing ### Description Parses an XML string into an `XMLIndexer` object for further processing. ### Method `parse` ### Endpoint N/A (Method on `XMLHash` struct) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body - **xmlToParse** (String) - Required - The XML string to be parsed. ### Request Example ```swift let xml = XMLHash.parse(xmlToParse) ``` ### Response - **XMLIndexer** - The parsed XML structure. ``` -------------------------------- ### Configuration API Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md SWXMLHash allows for configuration of its parsing behavior through the `configure` method. This section details the available configuration options and how to apply them. ```APIDOC ## Configuration API ### Description Allows for limited configuration in terms of its approach to parsing XML. ### Method `configure` ### Endpoint N/A (Method on `XMLHash` struct) ### Parameters #### Closure Parameters - **config** (`XMLHash.Config`) - Required - A closure where configuration options can be set. - `shouldProcessLazily` (Bool) - Optional - Determines whether to use lazy loading of the XML. Defaults to `false`. - `shouldProcessNamespaces` (Bool) - Optional - Forwards setting to `NSXMLParser` to return elements without namespace parts. Defaults to `false`. - `caseInsensitive` (Bool) - Optional - Allows for key lookups to be case-insensitive. Defaults to `false`. - `encoding` (String.Encoding) - Optional - Explicitly specifies the character encoding when an XML string is parsed. Defaults to `String.encoding.utf8`. - `userInfo` ([AnyHashable: Any]) - Optional - Mimics `Codable`'s `userInfo` property for contextual information. Defaults to `[:]`. - `detectParsingErrors` (Bool) - Optional - Attempts to detect XML parsing errors. Defaults to `false`. ### Request Example ```swift let xml = XMLHash.config { config in config.shouldProcessLazily = true config.caseInsensitive = true }.parse(xmlToParse) ``` ### Response N/A (Returns a configured `XMLIndexer` instance after parsing) ``` -------------------------------- ### Configure XML Namespace Processing Source: https://context7.com/drmohundro/swxmlhash/llms.txt Demonstrates how to parse XML with namespaces preserved or stripped by configuring the SWXMLHash parser. ```swift import SWXMLHash let xmlWithNamespace = """ Apples Bananas Coffee Table 80 120 """ // Parse with namespaces preserved (default) let xmlWithNS = XMLHash.parse(xmlWithNamespace) let fruit = xmlWithNS["root"]["h:table"]["h:tr"]["h:td"][0].element?.text // "Apples" // Parse with namespaces stripped let xmlWithoutNS = XMLHash.config { config in config.shouldProcessNamespaces = true }.parse(xmlWithNamespace) // Now access without namespace prefix let tableName = xmlWithoutNS["root"]["table"][1]["name"].element?.text // "Coffee Table" let tableWidth = xmlWithoutNS["root"]["table"][1]["width"].element?.text // "80" ``` -------------------------------- ### Configure the XML Parser Source: https://context7.com/drmohundro/swxmlhash/llms.txt Customize parsing behavior such as namespace processing, case sensitivity, and error detection using the configuration block. ```swift import SWXMLHash let xmlString = "Value" // Configure parser with multiple options let xml = XMLHash.config { config in // Enable lazy parsing for large files config.shouldProcessLazily = true // Strip XML namespaces (e.g., becomes ) config.shouldProcessNamespaces = true // Enable case-insensitive element lookup config.caseInsensitive = true // Set custom encoding (default is UTF-8) config.encoding = .utf8 // Enable parsing error detection config.detectParsingErrors = true // Add custom user info for deserialization context config.userInfo = [CodingUserInfoKey(rawValue: "apiVersion")!: "v2"] }.parse(xmlString) // Access elements (case-insensitive with config above) let element = xml["root"]["element"].element?.text // "Value" ``` -------------------------------- ### Add SWXMLHash as a Carthage Dependency Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md To integrate SWXMLHash with Carthage, add the specified GitHub repository and version to your Cartfile. ```plaintext github "drmohundro/SWXMLHash" ~> 7.0 ``` -------------------------------- ### Iterating Over Elements Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Demonstrates how to iterate over all elements at a given level or all child elements of a node. ```APIDOC ## Iterating Over Elements ### Description Provides methods to iterate over all elements at the current level or all direct child elements of a node. ### Method `all`, `children` ### Endpoint N/A (Operates on `XMLIndexer` instances) ### Parameters N/A ### Request Example ```swift // Iterate over all elements at the current level for elem in xml["root"]["catalog"]["book"].all { print(elem["genre"].element!.text!) } // Iterate over all child elements recursively func enumerate(indexer: XMLIndexer) { for child in indexer.children { print(child.element!.name) enumerate(child) } } enumerate(indexer: xml) ``` ### Response - **all** - Returns an array of `XMLIndexer` instances representing all elements at the current level. - **children** - Returns an array of `XMLIndexer` instances representing the direct child elements of the current node. ``` -------------------------------- ### Attribute Usage Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Shows how to retrieve attribute values from XML elements and how to look up elements based on their attributes. ```APIDOC ## Attribute Usage ### Description Provides methods to retrieve attribute values from XML elements and to find elements that possess specific attributes. ### Method `element(by:)`, `withAttribute(_:_: )` ### Endpoint N/A (Operates on `XMLIndexer` instances) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```swift // Get an attribute value xml["root"]["catalog"]["book"][1].element?.attribute(by: "id")?.text // Look up an element with a specific attribute xml["root"]["catalog"]["book"].withAttribute("id", "123")["author"].element?.text ``` ### Response - **attribute(by:)** - Returns an optional `XMLAttribute` object. - **withAttribute(_:_:)** - Returns an `XMLIndexer` instance containing elements that match the specified attribute and value. ``` -------------------------------- ### Element Lookup Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Demonstrates how to access specific elements within the parsed XML structure using key-based indexing. ```APIDOC ## Element Lookup ### Description Accesses specific elements within the parsed XML structure using key-based indexing, similar to dictionary lookups. ### Method Indexing (`[]`) ### Endpoint N/A (Operates on `XMLIndexer` instances) ### Parameters #### Path Parameters - **key** (String) - Required - The name of the element to access. ### Request Example ```swift // Single element lookup xml["root"]["header"]["title"].element?.text // Multiple elements lookup (accessing the second book) xml["root"]["catalog"]["book"][1]["author"].element?.text ``` ### Response - **XMLIndexer** - An `XMLIndexer` instance representing the found element or an empty indexer if not found. - **element?.text** - The text content of the element if found. ``` -------------------------------- ### Parse XML Strings and Data Source: https://context7.com/drmohundro/swxmlhash/llms.txt Initialize an XMLIndexer from a string or data object, with options for standard or lazy parsing. ```swift import SWXMLHash // Basic parsing from a string let xmlString = """
Welcome
Alice Bob
""" let xml = XMLHash.parse(xmlString) // Parse from Data let xmlData = xmlString.data(using: .utf8)! let xmlFromData = XMLHash.parse(xmlData) // Lazy parsing for large XML files (better memory performance) let lazyXml = XMLHash.lazy(xmlString) ``` -------------------------------- ### Work with XML Attributes Source: https://context7.com/drmohundro/swxmlhash/llms.txt Retrieve specific attributes, list all attributes, or filter elements based on attribute values. ```swift import SWXMLHash let xmlString = """ The Great Novel Jane Doe Swift Programming John Smith """ let xml = XMLHash.parse(xmlString) // Access a specific attribute - returns "101" let bookId = xml["root"]["catalog"]["book"][0].element?.attribute(by: "id")?.text // Get all attributes as dictionary let allAttrs = xml["root"]["catalog"]["book"][0].element?.allAttributes // ["id": XMLAttribute, "category": XMLAttribute, "inStock": XMLAttribute] // Access attribute name and text if let attr = xml["root"]["catalog"]["book"][0].element?.attribute(by: "category") { print("Attribute name: \(attr.name)") // "category" print("Attribute value: \(attr.text)") // "fiction" } // Find element by attribute value - returns "John Smith" let author = try xml["root"]["catalog"]["book"] .withAttribute("id", "102")["author"].element?.text ``` -------------------------------- ### Parse XML Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Basic XML parsing using `XMLHash.parse`. This is the simplest way to parse an XML string. ```swift let xml = XMLHash.parse(xmlToParse) ``` -------------------------------- ### Configure Lazy XML Parsing Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Configure XML parsing for lazy loading to improve performance with large XML files. This approach avoids loading the entire document into memory. ```swift let xml = XMLHash.config { config in config.shouldProcessLazily = true }.parse(xmlToParse) ``` -------------------------------- ### Implement NSDate deserialization Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Custom deserialization for NSDate class, requiring a generic helper to return Self. ```swift extension NSDate: XMLElementDeserializable { public static func deserialize(_ element: XMLElement) throws -> Self { guard let dateAsString = element.text else { throw XMLDeserializationError.nodeHasNoValue } let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz" let date = dateFormatter.dateFromString(dateAsString) guard let validDate = date else { throw XMLDeserializationError.typeConversionFailed(type: "Date", element: element) } // NOTE THIS return value(validDate) } // AND THIS private static func value(date: NSDate) -> T { return date as! T } } ``` -------------------------------- ### Access XML Elements Source: https://context7.com/drmohundro/swxmlhash/llms.txt Navigate the XML hierarchy using subscript syntax to retrieve element text, names, or inner content. ```swift import SWXMLHash let xmlString = """
My Document
Alice29.99 Bob19.99 Charlie24.99
""" let xml = XMLHash.parse(xmlString) // Single element lookup - returns "My Document" let title = xml["root"]["header"]["title"].element?.text // Access element by index - returns "Bob" let secondAuthor = xml["root"]["catalog"]["book"][1]["author"].element?.text // Get element name let elementName = xml["root"]["header"]["title"].element?.name // "title" // Access inner XML content let innerXml = xml["root"]["catalog"]["book"][0].element?.innerXML // "Alice29.99" // Get recursive text from element and all children let recursiveText = xml["root"]["catalog"]["book"][0].element?.recursiveText // "Alice29.99" ``` -------------------------------- ### Accessing XML with Enum Keys Source: https://context7.com/drmohundro/swxmlhash/llms.txt Define enums conforming to String to represent XML elements and attributes, then use them for subscript access and deserialization. ```swift import SWXMLHash let xmlString = """ Alice alice@example.com """ // Define enums for element keys enum UserElement: String { case name case email case settings } // Define enums for attribute keys enum UserAttribute: String { case id case role } enum SettingsAttribute: String { case theme case notifications } let xml = XMLHash.parse(xmlString) // Use enum keys for element access let userName = xml["root"]["user"][UserElement.name].element?.text // "Alice" let userEmail = xml["root"]["user"][UserElement.email].element?.text // "alice@example.com" // Use enum keys for attribute access let userId: String = try xml["root"]["user"].value(ofAttribute: UserAttribute.id) // "123" let userRole: String = try xml["root"]["user"].value(ofAttribute: UserAttribute.role) // "admin" // Use with withAttribute let adminUser = try xml["root"]["user"].withAttribute(UserAttribute.role, "admin") // Use enums in deserialization struct User: XMLObjectDeserialization { let id: String let role: String let name: String let email: String static func deserialize(_ node: XMLIndexer) throws -> User { return try User( id: node.value(ofAttribute: UserAttribute.id), role: node.value(ofAttribute: UserAttribute.role), name: node[UserElement.name].value(), email: node[UserElement.email].value() ) } } let user: User = try xml["root"]["user"].value() print("User: \(user.name), Role: \(user.role)") // "User: Alice, Role: admin" ``` -------------------------------- ### Add SWXMLHash as a Swift Package Manager Dependency Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md To add SWXMLHash as a dependency using Swift Package Manager, update your Package.swift file with the provided dependency URL and version. ```swift dependencies: [ .package(url: "https://github.com/drmohundro/SWXMLHash.git", from: "7.0.0") ] ``` -------------------------------- ### Retrieve Array of Custom Objects from XML Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md After defining a type that conforms to XMLObjectDeserialization, you can directly retrieve an array of these objects from a specific XML path. This simplifies data parsing significantly. ```swift let books: [Book] = try xml["root"]["books"]["book"].value() ``` -------------------------------- ### Implement Date deserialization Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Extends Date to conform to XMLValueDeserialization for custom parsing logic. ```swift extension Date: XMLValueDeserialization { public static func deserialize(_ element: XMLHash.XMLElement) throws -> Date { let date = stringToDate(element.text) guard let validDate = date else { throw XMLDeserializationError.typeConversionFailed(type: "Date", element: element) } return validDate } public static func deserialize(_ attribute: XMLAttribute) throws -> Date { let date = stringToDate(attribute.text) guard let validDate = date else { throw XMLDeserializationError.attributeDeserializationFailed(type: "Date", attribute: attribute) } return validDate } public func validate() throws { // empty validate... only necessary for custom validation logic after parsing } private static func stringToDate(_ dateAsString: String) -> Date? { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "EEEE, dd MMMM yyyy HH:mm:ss SSS" return dateFormatter.date(from: dateAsString) } } ``` -------------------------------- ### Iterate XML Elements Source: https://context7.com/drmohundro/swxmlhash/llms.txt Use the all property to access multiple elements at the same level or children to retrieve direct child nodes. Recursive enumeration can be implemented by traversing the children property. ```swift import SWXMLHash let xmlString = """ FictionBook A Non-fictionBook B TechnicalBook C """ let xml = XMLHash.parse(xmlString) // Get all elements at a level using .all let allBooks = xml["root"]["catalog"]["book"].all print("Book count: \(allBooks.count)") // 3 // Iterate using for-in on .all for book in xml["root"]["catalog"]["book"].all { if let title = book["title"].element?.text { print("Title: \(title)") } } // Map over elements - returns ["Fiction", "Non-fiction", "Technical"] let genres = xml["root"]["catalog"]["book"].all.map { elem in elem["genre"].element!.text } // Access all child elements of current level let bookChildren = xml["root"]["catalog"]["book"][0].children for child in bookChildren { print("Child element: \(child.element?.name ?? "")") // "genre", "title" } // Recursive enumeration of all elements func enumerate(indexer: XMLIndexer, level: Int) { for child in indexer.children { let indent = String(repeating: " ", count: level) print("\(indent)\(child.element?.name ?? "")") enumerate(indexer: child, level: level + 1) } } enumerate(indexer: xml, level: 0) ``` -------------------------------- ### Handle XML Parsing Errors Source: https://context7.com/drmohundro/swxmlhash/llms.txt Use do-catch blocks with IndexingError or pattern matching on XMLIndexer results to safely handle missing keys or invalid structures. ```swift import SWXMLHash let xmlString = """ Value """ let xml = XMLHash.parse(xmlString) // Method 1: Using do-catch with byKey/byIndex do { let element = try xml.byKey("root").byKey("nonexistent").byKey("item") print(element) } catch let error as IndexingError { switch error { case .key(let key): print("Missing key: \(key)") // "Missing key: nonexistent" case .index(let idx): print("Invalid index: \(idx)") case .attribute(let attr): print("Missing attribute: \(attr)") case .attributeValue(let attr, let value): print("No element with \(attr)=\(value)") default: print("Error: \(error)") } } // Method 2: Pattern matching with XMLIndexer switch xml["root"]["nonexistent"]["item"] { case .element(let elem): print("Found element: \(elem.name)") case .xmlError(let error): print("Error occurred: \(error)") // Prints error for missing key case .list(let elements): print("Found \(elements.count) elements") default: print("Unexpected result") } // Enable parsing error detection let xmlWithErrors = XMLHash.config { config in config.detectParsingErrors = true }.parse("") if case .parsingError(let error) = xmlWithErrors { print("Parsing failed: \(error)") } ``` -------------------------------- ### Lookup Multiple Elements by Index Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Retrieve the text of a specific element when multiple elements with the same name exist at the same level. Elements are accessed by their zero-based index. ```swift xml["root"]["catalog"]["book"][1]["author"].element?.text ``` -------------------------------- ### Implement XMLValueDeserialization for Custom Types Source: https://context7.com/drmohundro/swxmlhash/llms.txt Define custom deserialization logic by conforming to the XMLValueDeserialization protocol. This allows types to be parsed directly from XML elements and attributes. ```swift import SWXMLHash let xmlString = """ Conference 2024-06-15 2024-06-17 """ // Implement XMLValueDeserialization for Date extension Date: XMLValueDeserialization { public static func deserialize(_ element: XMLHash.XMLElement) throws -> Date { let dateString = element.text guard let date = dateFromString(dateString) else { throw XMLDeserializationError.typeConversionFailed( type: "Date", element: XMLElementSendable(element) ) } return date } public static func deserialize(_ attribute: XMLAttribute) throws -> Date { guard let date = dateFromString(attribute.text) else { throw XMLDeserializationError.attributeDeserializationFailed( type: "Date", attribute: attribute ) } return date } private static func dateFromString(_ string: String) -> Date? { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" return formatter.date(from: string) } } struct Event: XMLObjectDeserialization { let name: String let startDate: Date let endDate: Date static func deserialize(_ node: XMLIndexer) throws -> Event { return try Event( name: node["name"].value(), startDate: node["startDate"].value(), endDate: node["endDate"].value() ) } } struct Appointment: XMLObjectDeserialization { let title: String let date: Date static func deserialize(_ node: XMLIndexer) throws -> Appointment { return try Appointment( title: node.value(ofAttribute: "title"), date: node.value(ofAttribute: "date") // Date from attribute ) } } let xml = XMLHash.parse(xmlString) // Deserialize with custom Date conversion let event: Event = try xml["root"]["event"].value() print("Event: \(event.name)") // "Conference" let appointment: Appointment = try xml["root"]["appointment"].value() print("Appointment: \(appointment.title)") // "Meeting" ``` -------------------------------- ### Lookup Element with Specific Attribute Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Find an XML element that has a specific attribute with a given value, then access its child elements. This allows for targeted lookups based on attribute criteria. ```swift xml["root"]["catalog"]["book"].withAttribute("id", "123")["author"].element?.text ``` -------------------------------- ### Scope XMLElement to Avoid Ambiguity Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md When encountering an 'XMLElement' ambiguity error, scope it using `XMLHash.XMLElement` to resolve the conflict. -------------------------------- ### Lazy XML Parsing Directly Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Directly use the `XMLHash.lazy` method for parsing XML lazily, offering a more concise syntax than the `config` method for this specific option. ```swift let xml = XMLHash.lazy(xmlToParse) ``` -------------------------------- ### Deserialize Nested XML Structures in Swift Source: https://context7.com/drmohundro/swxmlhash/llms.txt Implements XMLObjectDeserialization and XMLElementDeserializable protocols to map deeply nested XML elements to Swift types. ```swift import SWXMLHash let xmlString = """ John Doe john@example.com Widget 9.99 Gadget 24.99 """ struct Customer: XMLObjectDeserialization { let name: String let email: String static func deserialize(_ node: XMLIndexer) throws -> Customer { return try Customer( name: node["name"].value(), email: node["email"].value() ) } } struct OrderItem: XMLObjectDeserialization { let sku: String let name: String let price: Double let quantity: Int static func deserialize(_ node: XMLIndexer) throws -> OrderItem { return try OrderItem( sku: node.value(ofAttribute: "sku"), name: node["name"].value(), price: node["price"].value(), quantity: node.value(ofAttribute: "quantity") ) } } struct Shipping: XMLElementDeserializable { let method: String let cost: Double static func deserialize(_ element: XMLHash.XMLElement) throws -> Shipping { return try Shipping( method: element.value(ofAttribute: "method"), cost: element.value(ofAttribute: "cost") ) } } struct Order: XMLObjectDeserialization { let id: String let customer: Customer let items: [OrderItem] let shipping: Shipping static func deserialize(_ node: XMLIndexer) throws -> Order { return try Order( id: node.value(ofAttribute: "id"), customer: node["customer"].value(), items: node["items"]["item"].value(), shipping: node["shipping"].value() ) } } let xml = XMLHash.parse(xmlString) let order: Order = try xml["root"]["order"].value() print("Order ID: \(order.id)") // "ORD-001" print("Customer: \(order.customer.name)") // "John Doe" print("Items: \(order.items.count)") // 2 print("First item: \(order.items[0].name)") // "Widget" print("Shipping: \(order.shipping.method)") // "express" // Calculate order total let itemsTotal = order.items.reduce(0.0) { $0 + ($1.price * Double($1.quantity)) } let total = itemsTotal + order.shipping.cost print("Order total: $\(total)") // "Order total: $59.97" ``` -------------------------------- ### Error Handling with Do-Catch in SWXMLHash Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Handle potential XML parsing errors using a do-catch block. This is useful when accessing elements that might not exist, preventing runtime crashes. The error is caught as an IndexingError. ```swift do { try xml!.byKey("root").byKey("what").byKey("header").byKey("foo") } catch let error as IndexingError { // error is an IndexingError instance that you can deal with } ``` -------------------------------- ### Recursively Enumerate Child Elements Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Recursively traverse the XML structure using the `children` property to access and process all descendant elements. This function prints the name of each element encountered. ```swift func enumerate(indexer: XMLIndexer) { for child in indexer.children { print(child.element!.name) enumerate(child) } } enumerate(indexer: xml) ``` -------------------------------- ### Error Handling with Switch Statement in SWXMLHash Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Handle XML parsing errors using a switch statement on the result of an indexing operation. This provides a clear way to differentiate between a successful element retrieval and an XML error. ```swift switch xml["root"]["what"]["header"]["foo"] { case .element(let elem): // everything is good, code away! case .xmlError(let error): // error is an IndexingError instance that you can deal with } ``` -------------------------------- ### Lookup Single Element Text Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Access the text content of a single XML element by chaining key lookups. Assumes the element and its text exist. ```swift xml["root"]["header"]["title"].element?.text ``` -------------------------------- ### Deserialize Custom Types with XMLObjectDeserialization Source: https://context7.com/drmohundro/swxmlhash/llms.txt Implement `XMLObjectDeserialization` to convert XML elements into custom Swift types. This is useful for complex XML structures with nested elements and attributes. Ensure all required fields are present or handled as optionals. ```swift import SWXMLHash let xmlString = """ Swift Programming 49.99 2023 Programming Mobile Development iOS Design Patterns 39.99 2022 5 Programming Software Architecture """ // Define a custom type implementing XMLObjectDeserialization struct Book: XMLObjectDeserialization { let title: String let price: Double let year: Int let amount: Int? // Optional field let isbn: String // From attribute let categories: [String] // Array from nested elements static func deserialize(_ node: XMLIndexer) throws -> Book { return try Book( title: node["title"].value(), price: node["price"].value(), year: node["year"].value(), amount: node["amount"].value(), // Returns nil if missing isbn: node.value(ofAttribute: "isbn"), categories: node["categories"]["category"].value() ) } } let xml = XMLHash.parse(xmlString) // Deserialize single element let firstBook: Book = try xml["root"]["books"]["book"][0].value() print("Title: \(firstBook.title)") // "Swift Programming" print("ISBN: \(firstBook.isbn)") // "978-0-123456-78-9" print("Categories: \(firstBook.categories)") // ["Programming", "Mobile Development"] // Deserialize array of elements let allBooks: [Book] = try xml["root"]["books"]["book"].value() print("Total books: \(allBooks.count)") // 2 // Deserialize to optional (returns nil if missing) let missingBook: Book? = try xml["root"]["books"]["missing"].value() print("Missing: \(missingBook == nil)") // true // Deserialize array of optionals let optionalBooks: [Book?] = try xml["root"]["books"]["book"].value() ``` -------------------------------- ### Retrieve custom deserialized value Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Usage of the value() method to parse XML into a Date object. ```swift let dt: Date = try xml["root"]["elem"].value() ``` -------------------------------- ### Filter XML Elements Source: https://context7.com/drmohundro/swxmlhash/llms.txt Apply filterAll or filterChildren to narrow down element sets based on attributes, indices, or child content. ```swift import SWXMLHash let xmlString = """ Gambardella, Matthew XML Developer's Guide Computer 44.95 Ralls, Kim Midnight Rain Fantasy 5.95 Corets, Eva Maeve Ascendant Fantasy 5.95 """ let xml = XMLHash.parse(xmlString) // Filter all elements by attribute value let filteredBook = xml["root"]["catalog"]["book"] .filterAll { elem, _ in elem.attribute(by: "id")?.text == "bk102" } print(filteredBook.element?.attribute(by: "id")?.text) // "bk102" // Filter by index (skip first element) let booksAfterFirst = xml["root"]["catalog"]["book"] .filterAll { _, index in index > 0 } // Returns books bk102 and bk103 // Filter children by index range let subIndexer = xml["root"]["catalog"]["book"][0] .filterChildren { _, index in index >= 1 && index <= 2 } // Returns only title and genre children (indices 1 and 2) // Combine filters let fantasyBooks = xml["root"]["catalog"]["book"] .filterAll { elem, _ in // Access child element to filter by genre let indexer = XMLIndexer(elem) return indexer["genre"].element?.text == "Fantasy" } ``` -------------------------------- ### Deserialize Elements with Attributes using XMLElementDeserializable Source: https://context7.com/drmohundro/swxmlhash/llms.txt Use `XMLElementDeserializable` to convert XML elements, particularly those defined by attributes, into custom Swift types. This is suitable for simpler XML structures where data is primarily stored in attributes. ```swift import SWXMLHash let xmlString = """ """ // Use XMLElementDeserializable for attribute-based elements struct Product: XMLElementDeserializable { let sku: String let name: String let price: Double let inStock: Bool static func deserialize(_ element: XMLHash.XMLElement) throws -> Product { return try Product( sku: element.value(ofAttribute: "sku"), name: element.value(ofAttribute: "name"), price: element.value(ofAttribute: "price"), inStock: element.value(ofAttribute: "inStock") ) } } let xml = XMLHash.parse(xmlString) // Deserialize single element let product: Product = try xml["root"]["products"]["product"][0].value() print("SKU: \(product.sku)") // "ABC123" print("In Stock: \(product.inStock)") // true // Deserialize all products let products: [Product] = try xml["root"]["products"]["product"].value() print("Product count: \(products.count)") // 3 // Filter and deserialize let inStockProducts = xml["root"]["products"]["product"] .filterAll { elem, _ in elem.attribute(by: "inStock")?.text == "true" } let available: [Product] = try inStockProducts.value() print("In stock: \(available.count)") // 2 ``` -------------------------------- ### Lookup Element Attribute by Name Source: https://github.com/drmohundro/swxmlhash/blob/main/README.md Access the value of a specific attribute of an XML element using the `attribute(by:)` method. Returns an optional attribute, from which text can be extracted. ```swift xml["root"]["catalog"]["book"][1].element?.attribute(by: "id")?.text ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.