<NME> ViewController.swift
<BEF> /**
 *  https://github.com/tadija/AEXML
 *  Copyright © Marko Tadić 2014-2021
 *  Licensed under the MIT license
 */

import UIKit
import AEXML

final class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var textView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        printExampleFromReadme()
    }

    private func printExampleFromReadme() {
        guard
            let xmlPath = Bundle.main.path(forResource: "example", ofType: "xml"),
            let data = try? Data(contentsOf: URL(fileURLWithPath: xmlPath))
        else {
            print("resource not found!")
            return
        }

        // example of using NSXMLParserOptions
        var options = AEXMLOptions()
        options.parserSettings.shouldProcessNamespaces = false
        options.parserSettings.shouldReportNamespacePrefixes = false
        options.parserSettings.shouldResolveExternalEntities = false

        do {
            let xmlDoc = try AEXMLDocument(xml: data, options: options)

            // prints the same XML structure as original
            print(xmlDoc.xml)

            // prints cats, dogs
            for child in xmlDoc.root.children {
            }
            
            // prints Optional("Tinna") (first element)
            print(xmlDoc.root["cats"]["cat"].value)
            
            // prints Tinna (first element)
            print(xmlDoc.root["cats"]["cat"].string)
            
            // prints Optional("Kika") (last element)
            print(xmlDoc.root["dogs"]["dog"].last?.value)
            
            // prints Betty (3rd element)
            print(xmlDoc.root["dogs"].children[2].string)
            print(xmlDoc.root["dogs"].children[2].string)

            // prints Tinna, Rose, Caesar
            if let cats = xmlDoc.root["cats"]["cat"].all {
                for cat in cats {
                    if let name = cat.value {
                        print(name)
                    }
                }
            }

            // prints Villy, Spot
            for dog in xmlDoc.root["dogs"]["dog"].all! {
                if let color = dog.attributes["color"] {
                    if color == "white" {
                        print(dog.string)
                    }
                }
            }

            // prints Tinna
            if let cats = xmlDoc.root["cats"]["cat"].all(withValue: "Tinna") {
                for cat in cats {
                    print(cat.string)
                }
            }

            // prints Caesar
            if let cats = xmlDoc.root["cats"]["cat"].all(withAttributes: ["breed" : "Domestic", "color" : "yellow"]) {
                for cat in cats {
                    print(cat.string)
                }
            }

            // prints 4
            print(xmlDoc.root["cats"]["cat"].count)

            // prints Siberian
            print(xmlDoc.root["cats"]["cat"].attributes["breed"]!)

            print(xmlDoc.root["cats"]["cat"].xmlCompact)
            
            // prints Optional(AEXML.AEXMLError.elementNotFound)
            print(xmlDoc["NotExistingElement"].error)
        }
        catch {
            print("\(error)")
        }
    }
    
    @IBAction func readXML(_ sender: UIBarButtonItem) {
        defer {
            resetTextField()
        }
        
        guard let
            xmlPath = Bundle.main.path(forResource: "plant_catalog", ofType: "xml"),
            let data = try? Data(contentsOf: URL(fileURLWithPath: xmlPath))
        else {
            textView.text = "Sample XML Data error."
            return
        }
        
        do {
            let document = try AEXMLDocument(xml: data)
            var parsedText = String()
            // parse known structure
            for plant in document["CATALOG"]["PLANT"].all! {
                parsedText += plant["COMMON"].string + "\n"
            }
            textView.text = parsedText
        } catch {
            textView.text = "\(error)"
        }
    }
    
    @IBAction func writeXML(_ sender: UIBarButtonItem) {
        resetTextField()
        // sample SOAP request
        let soapRequest = AEXMLDocument()
        let attributes = ["xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" : "http://www.w3.org/2001/XMLSchema"]
        let envelope = soapRequest.addChild(name: "soap:Envelope", attributes: attributes)
        let header = envelope.addChild(name: "soap:Header")
        let body = envelope.addChild(name: "soap:Body")
        header.addChild(name: "m:Trans", value: "234", attributes: ["xmlns:m" : "http://www.w3schools.com/transaction/", "soap:mustUnderstand" : "1"])
        let getStockPrice = body.addChild(name: "m:GetStockPrice")
        getStockPrice.addChild(name: "m:StockName", value: "AAPL")
        textView.text = soapRequest.xml
    }
    
    func resetTextField() {
        textField.resignFirstResponder()
        textField.text = "http://www.w3schools.com/xml/cd_catalog.xml"
    }
    
    @IBAction func tryRemoteXML(_ sender: UIButton) {
        defer {
            textField.resignFirstResponder()
        }

        guard
            let text = textField.text,
            let url = URL(string: text),
            let data = try? Data(contentsOf: url)
        else {
            textView.text = "Bad URL or XML Data."
            return
        }

        do {
            let document = try AEXMLDocument(xml: data)
            var parsedText = String()
            // parse unknown structure
            for child in document.root.children {
                parsedText += child.xml + "\n"
            }
            textView.text = parsedText
        } catch {
            textView.text = "\(error)"
        }
    }

}

<MSG> Fixed few build warnings in demo project

<DFF> @@ -44,13 +44,13 @@ class ViewController: UIViewController {
             }
             
             // prints Optional("Tinna") (first element)
-            print(xmlDoc.root["cats"]["cat"].value)
+            print(String(describing: xmlDoc.root["cats"]["cat"].value))
             
             // prints Tinna (first element)
             print(xmlDoc.root["cats"]["cat"].string)
             
             // prints Optional("Kika") (last element)
-            print(xmlDoc.root["dogs"]["dog"].last?.value)
+            print(String(describing: xmlDoc.root["dogs"]["dog"].last?.value))
             
             // prints Betty (3rd element)
             print(xmlDoc.root["dogs"].children[2].string)
@@ -97,7 +97,7 @@ class ViewController: UIViewController {
             print(xmlDoc.root["cats"]["cat"].xmlCompact)
             
             // prints Optional(AEXML.AEXMLError.elementNotFound)
-            print(xmlDoc["NotExistingElement"].error)
+            print(String(describing: xmlDoc["NotExistingElement"].error))
         }
         catch {
             print("\(error)")

{'commit': 'diff --git a/Example/AEXMLDemo/ViewController.swift b/Example/AEXMLDemo/ViewController.swift\nindex 7a743f8..910641c 100644\n--- a/Example/AEXMLDemo/ViewController.swift\n+++ b/Example/AEXMLDemo/ViewController.swift\n@@ -44,13 +44,13 @@ class ViewController: UIViewController {\n             }\n             \n             // prints Optional("Tinna") (first element)\n-            print(xmlDoc.root["cats"]["cat"].value)\n+            print(String(describing: xmlDoc.root["cats"]["cat"].value))\n             \n             // prints Tinna (first element)\n             print(xmlDoc.root["cats"]["cat"].string)\n             \n             // prints Optional("Kika") (last element)\n-            print(xmlDoc.root["dogs"]["dog"].last?.value)\n+            print(String(describing: xmlDoc.root["dogs"]["dog"].last?.value))\n             \n             // prints Betty (3rd element)\n             print(xmlDoc.root["dogs"].children[2].string)\n@@ -97,7 +97,7 @@ class ViewController: UIViewController {\n             print(xmlDoc.root["cats"]["cat"].xmlCompact)\n             \n             // prints Optional(AEXML.AEXMLError.elementNotFound)\n-            print(xmlDoc["NotExistingElement"].error)\n+            print(String(describing: xmlDoc["NotExistingElement"].error))\n         }\n         catch {\n             print("\\(error)")\n', 'commit_subject': 'Fixed few build warnings in demo project', 'repo_name': 'tadija/AEXML', 'committer': {'name': 'Marko Tadic', 'email': 'a6eeab2cbe84e0c695734078731b42d4cfc3f17d@me.com', 'time_sec': '1511636492', 'tz_offset': '60', 'date': {'seconds': '1511636492'}}, 'commit_tree': '7a942f1f637e33e3ab409fcf0472ba6160d11bae', 'commit_message': 'Fixed few build warnings in demo project\n', 'language_name': 'Swift', 'license': 'mit', 'hunks': '@@ -44,13 +44,13 @@ class ViewController: UIViewController {\n             }\n             \n             // prints Optional("Tinna") (first element)\n-            print(xmlDoc.root["cats"]["cat"].value)\n+            print(String(describing: xmlDoc.root["cats"]["cat"].value))\n             \n             // prints Tinna (first element)\n             print(xmlDoc.root["cats"]["cat"].string)\n             \n             // prints Optional("Kika") (last element)\n-            print(xmlDoc.root["dogs"]["dog"].last?.value)\n+            print(String(describing: xmlDoc.root["dogs"]["dog"].last?.value))\n             \n             // prints Betty (3rd element)\n             print(xmlDoc.root["dogs"].children[2].string)\n@@ -97,7 +97,7 @@ class ViewController: UIViewController {\n             print(xmlDoc.root["cats"]["cat"].xmlCompact)\n             \n             // prints Optional(AEXML.AEXMLError.elementNotFound)\n-            print(xmlDoc["NotExistingElement"].error)\n+            print(String(describing: xmlDoc["NotExistingElement"].error))\n         }\n         catch {\n             print("\\(error)")\n', 'addition_count': 3, 'deletion_count': 3, 'src_file': 'a/Example/AEXMLDemo/ViewController.swift', 'tgt_file': 'b/Example/AEXMLDemo/ViewController.swift', 'file_extension': '.swift', 'before_file': '/**\n *  https://github.com/tadija/AEXML\n *  Copyright © Marko Tadić 2014-2021\n *  Licensed under the MIT license\n */\n\nimport UIKit\nimport AEXML\n\nfinal class ViewController: UIViewController {\n\n    @IBOutlet weak var textField: UITextField!\n    @IBOutlet weak var textView: UITextView!\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        printExampleFromReadme()\n    }\n\n    private func printExampleFromReadme() {\n        guard\n            let xmlPath = Bundle.main.path(forResource: "example", ofType: "xml"),\n            let data = try? Data(contentsOf: URL(fileURLWithPath: xmlPath))\n        else {\n            print("resource not found!")\n            return\n        }\n\n        // example of using NSXMLParserOptions\n        var options = AEXMLOptions()\n        options.parserSettings.shouldProcessNamespaces = false\n        options.parserSettings.shouldReportNamespacePrefixes = false\n        options.parserSettings.shouldResolveExternalEntities = false\n\n        do {\n            let xmlDoc = try AEXMLDocument(xml: data, options: options)\n\n            // prints the same XML structure as original\n            print(xmlDoc.xml)\n\n            // prints cats, dogs\n            for child in xmlDoc.root.children {\n            }\n            \n            // prints Optional("Tinna") (first element)\n            print(xmlDoc.root["cats"]["cat"].value)\n            \n            // prints Tinna (first element)\n            print(xmlDoc.root["cats"]["cat"].string)\n            \n            // prints Optional("Kika") (last element)\n            print(xmlDoc.root["dogs"]["dog"].last?.value)\n            \n            // prints Betty (3rd element)\n            print(xmlDoc.root["dogs"].children[2].string)\n            print(xmlDoc.root["dogs"].children[2].string)\n\n            // prints Tinna, Rose, Caesar\n            if let cats = xmlDoc.root["cats"]["cat"].all {\n                for cat in cats {\n                    if let name = cat.value {\n                        print(name)\n                    }\n                }\n            }\n\n            // prints Villy, Spot\n            for dog in xmlDoc.root["dogs"]["dog"].all! {\n                if let color = dog.attributes["color"] {\n                    if color == "white" {\n                        print(dog.string)\n                    }\n                }\n            }\n\n            // prints Tinna\n            if let cats = xmlDoc.root["cats"]["cat"].all(withValue: "Tinna") {\n                for cat in cats {\n                    print(cat.string)\n                }\n            }\n\n            // prints Caesar\n            if let cats = xmlDoc.root["cats"]["cat"].all(withAttributes: ["breed" : "Domestic", "color" : "yellow"]) {\n                for cat in cats {\n                    print(cat.string)\n                }\n            }\n\n            // prints 4\n            print(xmlDoc.root["cats"]["cat"].count)\n\n            // prints Siberian\n            print(xmlDoc.root["cats"]["cat"].attributes["breed"]!)\n\n            print(xmlDoc.root["cats"]["cat"].xmlCompact)\n            \n            // prints Optional(AEXML.AEXMLError.elementNotFound)\n            print(xmlDoc["NotExistingElement"].error)\n        }\n        catch {\n            print("\\(error)")\n        }\n    }\n    \n    @IBAction func readXML(_ sender: UIBarButtonItem) {\n        defer {\n            resetTextField()\n        }\n        \n        guard let\n            xmlPath = Bundle.main.path(forResource: "plant_catalog", ofType: "xml"),\n            let data = try? Data(contentsOf: URL(fileURLWithPath: xmlPath))\n        else {\n            textView.text = "Sample XML Data error."\n            return\n        }\n        \n        do {\n            let document = try AEXMLDocument(xml: data)\n            var parsedText = String()\n            // parse known structure\n            for plant in document["CATALOG"]["PLANT"].all! {\n                parsedText += plant["COMMON"].string + "\\n"\n            }\n            textView.text = parsedText\n        } catch {\n            textView.text = "\\(error)"\n        }\n    }\n    \n    @IBAction func writeXML(_ sender: UIBarButtonItem) {\n        resetTextField()\n        // sample SOAP request\n        let soapRequest = AEXMLDocument()\n        let attributes = ["xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" : "http://www.w3.org/2001/XMLSchema"]\n        let envelope = soapRequest.addChild(name: "soap:Envelope", attributes: attributes)\n        let header = envelope.addChild(name: "soap:Header")\n        let body = envelope.addChild(name: "soap:Body")\n        header.addChild(name: "m:Trans", value: "234", attributes: ["xmlns:m" : "http://www.w3schools.com/transaction/", "soap:mustUnderstand" : "1"])\n        let getStockPrice = body.addChild(name: "m:GetStockPrice")\n        getStockPrice.addChild(name: "m:StockName", value: "AAPL")\n        textView.text = soapRequest.xml\n    }\n    \n    func resetTextField() {\n        textField.resignFirstResponder()\n        textField.text = "http://www.w3schools.com/xml/cd_catalog.xml"\n    }\n    \n    @IBAction func tryRemoteXML(_ sender: UIButton) {\n        defer {\n            textField.resignFirstResponder()\n        }\n\n        guard\n            let text = textField.text,\n            let url = URL(string: text),\n            let data = try? Data(contentsOf: url)\n        else {\n            textView.text = "Bad URL or XML Data."\n            return\n        }\n\n        do {\n            let document = try AEXMLDocument(xml: data)\n            var parsedText = String()\n            // parse unknown structure\n            for child in document.root.children {\n                parsedText += child.xml + "\\n"\n            }\n            textView.text = parsedText\n        } catch {\n            textView.text = "\\(error)"\n        }\n    }\n\n}\n', 'message': 'Fixed few build warnings in demo project\n', 'author_name': 'Marko Tadic', 'lang': 'swift'}