--- /dev/null
+import Foundation
+
+/**
+ This class is inherited from `AEXMLElement` and has a few addons to represent **XML Document**.
+
+ XML Parsing is also done with this object.
+*/
+open class AEXMLDocument: AEXMLElement {
+
+ // MARK: - Properties
+
+ /// Root (the first child element) element of XML Document **(Empty element with error if not exists)**.
+ open var root: AEXMLElement {
+ guard let rootElement = children.first else {
+ let errorElement = AEXMLElement(name: "Error")
+ errorElement.error = AEXMLError.rootElementMissing
+ return errorElement
+ }
+ return rootElement
+ }
+
+ open let options: AEXMLOptions
+
+ // MARK: - Lifecycle
+
+ /**
+ Designated initializer - Creates and returns new XML Document object.
+
+ - parameter root: Root XML element for XML Document (defaults to `nil`).
+ - parameter options: Options for XML Document header and parser settings (defaults to `AEXMLOptions()`).
+
+ - returns: Initialized XML Document object.
+ */
+ public init(root: AEXMLElement? = nil, options: AEXMLOptions = AEXMLOptions()) {
+ self.options = options
+
+ let documentName = String(describing: AEXMLDocument.self)
+ super.init(name: documentName)
+
+ // document has no parent element
+ parent = nil
+
+ // add root element to document (if any)
+ if let rootElement = root {
+ _ = addChild(rootElement)
+ }
+ }
+
+ /**
+ Convenience initializer - used for parsing XML data (by calling `loadXMLData:` internally).
+
+ - parameter xmlData: XML data to parse.
+ - parameter options: Options for XML Document header and parser settings (defaults to `AEXMLOptions()`).
+
+ - returns: Initialized XML Document object containing parsed data. Throws error if data could not be parsed.
+ */
+ public convenience init(xml: Data, options: AEXMLOptions = AEXMLOptions()) throws {
+ self.init(options: options)
+ try loadXML(xml)
+ }
+
+ /**
+ Convenience initializer - used for parsing XML string (by calling `init(xmlData:options:)` internally).
+
+ - parameter xmlString: XML string to parse.
+ - parameter encoding: String encoding for creating `Data` from `xmlString` (defaults to `String.Encoding.utf8`)
+ - parameter options: Options for XML Document header and parser settings (defaults to `AEXMLOptions()`).
+
+ - returns: Initialized XML Document object containing parsed data. Throws error if data could not be parsed.
+ */
+ public convenience init(xml: String,
+ encoding: String.Encoding = String.Encoding.utf8,
+ options: AEXMLOptions = AEXMLOptions()) throws
+ {
+ guard let data = xml.data(using: encoding) else { throw AEXMLError.parsingFailed }
+ try self.init(xml: data, options: options)
+ }
+
+ // MARK: - Parse XML
+
+ /**
+ Creates instance of `AEXMLParser` (private class which is simple wrapper around `XMLParser`)
+ and starts parsing the given XML data. Throws error if data could not be parsed.
+
+ - parameter data: XML which should be parsed.
+ */
+ open func loadXML(_ data: Data) throws {
+ children.removeAll(keepingCapacity: false)
+ let xmlParser = AEXMLParser(document: self, data: data)
+ try xmlParser.parse()
+ }
+
+ // MARK: - Override
+
+ /// Override of `xml` property of `AEXMLElement` - it just inserts XML Document header at the beginning.
+ open override var xml: String {
+ var xml = "\(options.documentHeader.xmlString)\n"
+ xml += root.xml
+ return xml
+ }
+
+}