1 /** 2 * Copyright © DiamondMVC 2019 3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module diamond.xml.xmldocument; 7 8 import diamond.xml.xmlexception; 9 import diamond.dom.domdocument; 10 import diamond.dom.domnode; 11 import diamond.dom.domparsersettings; 12 import diamond.xml.xmlnode; 13 14 /// An XML document. 15 final class XmlDocument : DomDocument 16 { 17 private: 18 /// The version of the xml document. 19 string _xmlVersion; 20 /// The encoding of the xml document. 21 string _encoding; 22 /// The root node of the document. 23 XmlNode _root; 24 25 public: 26 final: 27 /** 28 * Creates a new xml document. 29 * Params: 30 * parserSettings = The settings used for parsing the document. 31 */ 32 this(DomParserSettings parserSettings) @safe 33 { 34 super(parserSettings); 35 } 36 37 /** 38 * Parses the elements from the dom to the document. 39 * Params: 40 * elements = The parsed dom elements. 41 */ 42 override void parseElements(DomNode[] elements) @safe 43 { 44 if (!elements || elements.length != 2) 45 { 46 throw new XmlException("No xml header found or no root element found."); 47 } 48 49 auto header = elements[0]; 50 _root = elements[1]; 51 52 auto versionAttribute = header.getAttribute("version"); 53 auto encodingAttribute = header.getAttribute("encoding"); 54 55 import std..string : strip; 56 57 _xmlVersion = versionAttribute ? versionAttribute.value.strip() : null; 58 _encoding = encodingAttribute ? encodingAttribute.value.strip() : "UTF-8"; 59 } 60 61 @property 62 { 63 /// Gets the version of the xml document. 64 string xmlVersion() @safe { return _xmlVersion; } 65 66 /// Sets the version of the xml document. 67 void xmlVersion(string newXmlVersion) @safe 68 { 69 _xmlVersion = newXmlVersion; 70 71 if (!_xmlVersion || !_xmlVersion.length) 72 { 73 throw new XmlException("No xml version found."); 74 } 75 } 76 77 /// Gets the encoding of the xml document. 78 string encoding() @safe { return _encoding; } 79 80 /// Sets the encoding of the xml document. 81 void encoding(string newEncoding) @safe 82 { 83 _encoding = newEncoding; 84 85 if (!_encoding || !_encoding.length) 86 { 87 throw new XmlException("Empty encoding specified."); 88 } 89 } 90 91 /// Gets the root of the xml document. 92 XmlNode root() @safe { return _root; } 93 94 /// Sets the root node of the xml document. 95 void root(XmlNode newRoot) @safe 96 { 97 _root = newRoot; 98 } 99 } 100 101 /// XML documents cannot be repaired. 102 override void repairDocument() @safe 103 { 104 throw new XmlException("Cannot repair XML documents."); 105 } 106 107 /** 108 * Converts the xml document to a properly formatted xml document-string. 109 * Returns: 110 * A string equivalent to the properly formatted xml document-string. 111 */ 112 override string toString() @safe 113 { 114 import std..string : format; 115 116 return "<?xml version=\"%s\" encoding=\"%s\"?>\r\n%s".format(_xmlVersion, _encoding && _encoding.length ? _encoding : "UTF-8", _root ? _root.toString() : ""); 117 } 118 }