1 module deepmagic.dom.xml.document; 2 3 import deepmagic.dom; 4 5 class Document : Element 6 { 7 /** 8 * Contains all text which occurs before the root element. 9 * Defaults to <?xml version="1.0"?> 10 */ 11 string prolog = "<?xml version=\"1.0\"?>"; 12 /** 13 * Contains all text which occurs after the root element. 14 * Defaults to the empty string 15 */ 16 string epilog; 17 18 /** 19 * Constructs a Document by parsing XML text. 20 * 21 * This function creates a complete DOM (Document Object Model) tree. 22 * 23 * The input to this function MUST be valid XML. 24 * This is enforced by DocumentParser's in contract. 25 * 26 * Params: 27 * s = the complete XML text. 28 */ 29 this(string s) 30 in 31 { 32 assert(s.length != 0); 33 } 34 body 35 { 36 auto xml = new DocumentParser(s); 37 string tagString = xml.tag.tagString; 38 39 this(xml.tag); 40 prolog = s[0 .. tagString.ptr - s.ptr]; 41 this.parse(xml); 42 epilog = *xml.s; 43 } 44 45 /** 46 * Constructs a Document from a Tag. 47 * 48 * Params: 49 * tag = the start tag of the document. 50 */ 51 this(const(Tag) tag) 52 { 53 super(tag); 54 } 55 56 const 57 { 58 /** 59 * Compares two Documents for equality 60 * 61 * Examples: 62 * -------------- 63 * Document d1,d2; 64 * if (d1 == d2) { } 65 * -------------- 66 */ 67 override bool opEquals(Object o) 68 { 69 const doc = toType!(const Document)(o); 70 return 71 (prolog != doc.prolog ) ? false : ( 72 (super != cast(const Element)doc) ? false : ( 73 (epilog != doc.epilog ) ? false : ( 74 true ))); 75 } 76 77 /** 78 * Compares two Documents 79 * 80 * You should rarely need to call this function. It exists so that 81 * Documents can be used as associative array keys. 82 * 83 * Examples: 84 * -------------- 85 * Document d1,d2; 86 * if (d1 < d2) { } 87 * -------------- 88 */ 89 override int opCmp(Object o) 90 { 91 const doc = toType!(const Document)(o); 92 return 93 ((prolog != doc.prolog ) 94 ? ( prolog < doc.prolog ? -1 : 1 ) : 95 ((super != cast(const Element)doc) 96 ? ( cast()super < cast()cast(const Element)doc ? -1 : 1 ) : 97 ((epilog != doc.epilog ) 98 ? ( epilog < doc.epilog ? -1 : 1 ) : 99 0 ))); 100 } 101 102 /** 103 * Returns the hash of a Document 104 * 105 * You should rarely need to call this function. It exists so that 106 * Documents can be used as associative array keys. 107 */ 108 override size_t toHash() @trusted 109 { 110 return hash(prolog, hash(epilog, (cast()super).toHash())); 111 } 112 113 /** 114 * Returns the string representation of a Document. (That is, the 115 * complete XML of a document). 116 */ 117 override string toString() 118 { 119 return prolog ~ super.toString() ~ epilog; 120 } 121 } 122 }