export function XMLWriter(encoding, version) { if (encoding) this.encoding = encoding; if (version) this.version = version; }; (function () { function FormatXML(Str) { Str = "" + Str; return Str.replace(/&/g, "&").replace(/\"/g, """).replace(//g, ">").replace(/'/g, "'"); } XMLWriter.prototype = { encoding: 'ISO-8859-1',// what is the encoding version: '1.0', //what xml version to use formatting: 'indented', //how to format the output (indented/none) ? indentChar: '\t', //char to use for indent indentation: 1, //how many indentChar to add per level newLine: '\n', //character to separate nodes when formatting //start a new document, cleanup if we are reusing writeStartDocument: function (standalone) { this.close();//cleanup this.stack = []; this.standalone = standalone; }, //get back to the root writeEndDocument: function () { this.active = this.root; this.stack = []; }, //set the text of the doctype writeDocType: function (dt) { this.doctype = dt; }, //start a new node with this name, and an optional namespace writeStartElement: function (name, ns) { if (ns)//namespace name = ns + ':' + name; var node = { n: name, a: {}, c: [] };//(n)ame, (a)ttributes, (c)hildren if (this.active) { this.active.c.push(node); this.stack.push(this.active); } else this.root = node; this.active = node; }, //go up one node, if we are in the root, ignore it writeEndElement: function () { this.active = this.stack.pop() || this.root; }, //add an attribute to the active node writeAttributeString: function (name, value) { if (this.active) this.active.a[name] = "" + FormatXML(value).replace(/\n/g, ''); }, //add a text node to the active node writeString: function (text) { if (this.active) this.active.c.push("" + FormatXML(text)); }, //shortcut, open an element, write the text and close writeElementString: function (name, text, ns) { this.writeStartElement(name, ns); this.writeString(text); this.writeEndElement(); }, //add a text node wrapped with CDATA writeCDATA: function (text) { if (this.active) this.active.c.push(''); }, //add a text node wrapped in a comment writeComment: function (text) { if (this.active) this.active.c.push(''); }, //generate the xml string, you can skip closing the last nodes flush: function (showHeader) { if (this.stack && this.stack[0])//ensure it's closed this.writeEndDocument(); var chr = '', indent = '', num = this.indentation, formatting = this.formatting.toLowerCase() == 'indented', buffer = ""; if (showHeader) { buffer = ''; } if (buffer !== "") //@ts-ignore buffer = [buffer]; else //@ts-ignore buffer = []; if (this.doctype && this.root) //@ts-ignore buffer.push(''); if (formatting) { while (num--) chr += this.indentChar; } if (this.root)//skip if no element was added format(this.root, indent, chr, buffer); //@ts-ignore return buffer.join(formatting ? this.newLine : ''); }, //cleanup, don't use again without calling startDocument close: function () { if (this.root) clean(this.root); this.active = this.root = this.stack = null; }, //@ts-ignore getDocument: window.ActiveXObject ? function () { //MSIE //@ts-ignore var doc = new ActiveXObject('Microsoft.XMLDOM'); doc.async = false; doc.loadXML(this.flush()); return doc; } : function () {// Mozilla, Firefox, Opera, etc. //@ts-ignore return (new DOMParser()).parseFromString(this.flush(), 'text/xml'); } }; //utility, you don't need it function clean(node) { var l = node.c.length; while (l--) { if (typeof node.c[l] == 'object') clean(node.c[l]); } node.n = node.a = node.c = null; }; //utility, you don't need it function format(node, indent, chr, buffer) { var xml = indent + '<' + node.n, nc = node.c.length, attr, child, i = 0; for (attr in node.a) xml += ' ' + attr + '="' + node.a[attr] + '"'; xml += nc ? '>' : ' />'; buffer.push(xml); if (nc) { do { child = node.c[i++]; if (typeof child == 'string') { if (nc == 1)//single text node return buffer.push(buffer.pop() + child + ''); else //regular text node buffer.push(indent + chr + child); } else if (typeof child == 'object') //element node format(child, indent + chr, chr, buffer); } while (i < nc); buffer.push(indent + ''); } }; })();