| [1073] | 1 | //////////////////////////////////////////////////////////
 | 
|---|
 | 2 | ////////// JSXML XML Tools                    ////////////
 | 
|---|
 | 3 | ////////// Ver 1.3 Aug 29 2009                ////////////
 | 
|---|
 | 4 | ////////// Copyright 2000-2009 Peter Tracey   ////////////
 | 
|---|
 | 5 | ////////// http://levelthreesoltions.com/jsxml/
 | 
|---|
 | 6 | ////
 | 
|---|
 | 7 | ////    Objects:
 | 
|---|
 | 8 | ////
 | 
|---|
 | 9 | ////    REXML
 | 
|---|
 | 10 | ////    Regular Expression-based XML parser
 | 
|---|
 | 11 | ////
 | 
|---|
 | 12 | ////    JSXMLIterator
 | 
|---|
 | 13 | ////    Iterates through the tree structure without recursion
 | 
|---|
 | 14 | ////
 | 
|---|
 | 15 | ////    JSXMLBuilder
 | 
|---|
 | 16 | ////    Loads xml into a linear structure and provides 
 | 
|---|
 | 17 | ////    interface for adding and removing elements 
 | 
|---|
 | 18 | ////    and setting attributes, generates XML
 | 
|---|
 | 19 | ////
 | 
|---|
 | 20 | ////    Utility functions:
 | 
|---|
 | 21 | ////
 | 
|---|
 | 22 | ////    ParseAttribute
 | 
|---|
 | 23 | ////    Takes string of attibutes and attribute name
 | 
|---|
 | 24 | ////    Returns attribute value
 | 
|---|
 | 25 | ////
 | 
|---|
 | 26 | ////    Array_Remove
 | 
|---|
 | 27 | ////    Removes element in array
 | 
|---|
 | 28 | ////
 | 
|---|
 | 29 | ////    Array_Add
 | 
|---|
 | 30 | ////    Adds element to array
 | 
|---|
 | 31 | ////
 | 
|---|
 | 32 | ////    RepeatChar
 | 
|---|
 | 33 | ////    Repeats string specified number of times
 | 
|---|
 | 34 | ////
 | 
|---|
 | 35 | ///////////////////////////////////////////////////////////////
 | 
|---|
 | 36 | 
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 | function REXML(XML) {
 | 
|---|
 | 39 |         this.XML = XML;
 | 
|---|
 | 40 | 
 | 
|---|
 | 41 |         this.rootElement = null;
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 |         this.parse = REXML_parse;
 | 
|---|
 | 44 |         if (this.XML && this.XML !== "") this.parse();
 | 
|---|
 | 45 | }
 | 
|---|
 | 46 | 
 | 
|---|
 | 47 |         function REXML_parse() {
 | 
|---|
 | 48 |                 var reTag = new RegExp("<([^>/ ]*)([^>]*)>","g"); // matches that tag name $1 and attribute string $2
 | 
|---|
 | 49 |                 var reTagText = new RegExp("<([^>/ ]*)([^>]*)>([^<]*)","g"); // matches tag name $1, attribute string $2, and text $3
 | 
|---|
 | 50 |                 var strType = "";
 | 
|---|
 | 51 |                 var strTag = "";
 | 
|---|
 | 52 |                 var strText = "";
 | 
|---|
 | 53 |                 var strAttributes = "";
 | 
|---|
 | 54 |                 var strOpen = "";
 | 
|---|
 | 55 |                 var strClose = "";
 | 
|---|
 | 56 |                 var iElements = 0;
 | 
|---|
 | 57 |                 var xmleLastElement = null;
 | 
|---|
 | 58 |                 if (this.XML.length === 0) return;
 | 
|---|
 | 59 |                 var arrElementsUnparsed = this.XML.match(reTag);
 | 
|---|
 | 60 |                 var arrElementsUnparsedText = this.XML.match(reTagText);
 | 
|---|
 | 61 |                 var i=0;
 | 
|---|
 | 62 |                 if (arrElementsUnparsed[0].replace(reTag, "$1") == "?xml") i++;
 | 
|---|
 | 63 | 
 | 
|---|
 | 64 |                 for (; i<arrElementsUnparsed.length; i++) {
 | 
|---|
 | 65 |                         strTag = arrElementsUnparsed[i].replace(reTag,"$1");
 | 
|---|
 | 66 |                         strAttributes = arrElementsUnparsed[i].replace(reTag,"$2");
 | 
|---|
 | 67 |                         strText = arrElementsUnparsedText[i].replace(reTagText,"$3").replace(/[\r\n\t ]+/g, " "); // remove white space
 | 
|---|
 | 68 |                         strClose = "";
 | 
|---|
 | 69 |                         if (strTag.indexOf("![CDATA[") === 0) {
 | 
|---|
 | 70 |                                 strOpen = "<![CDATA[";
 | 
|---|
 | 71 |                                 strClose = "]]>";
 | 
|---|
 | 72 |                                 strType = "cdata";
 | 
|---|
 | 73 |                         } else if (strTag.indexOf("!--") === 0) {
 | 
|---|
 | 74 |                                 strOpen = "<!--";
 | 
|---|
 | 75 |                                 strClose = "-->";
 | 
|---|
 | 76 |                                 strType = "comment";
 | 
|---|
 | 77 |                         } else if (strTag.indexOf("?") === 0) {
 | 
|---|
 | 78 |                                 strOpen = "<?";
 | 
|---|
 | 79 |                                 strClose = "?>";
 | 
|---|
 | 80 |                                 strType = "pi";
 | 
|---|
 | 81 |                         } else strType = "element";
 | 
|---|
 | 82 |                         if (strClose !== "") {
 | 
|---|
 | 83 |                                 strText = "";
 | 
|---|
 | 84 |                                 if (arrElementsUnparsedText[i].indexOf(strClose) > -1) strText = arrElementsUnparsedText[i];
 | 
|---|
 | 85 |                                 else {
 | 
|---|
 | 86 |                                         for (; i<arrElementsUnparsed.length && arrElementsUnparsedText[i].indexOf(strClose) == -1; i++) {
 | 
|---|
 | 87 |                                                 strText += arrElementsUnparsedText[i];
 | 
|---|
 | 88 |                                         }
 | 
|---|
 | 89 |                                         strText += arrElementsUnparsedText[i];
 | 
|---|
 | 90 |                                 }
 | 
|---|
 | 91 |                                 if (strText.substring(strOpen.length, strText.indexOf(strClose)) !== "")        {
 | 
|---|
 | 92 |                                         xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement(strType, "","",xmleLastElement,strText.substring(strOpen.length, strText.indexOf(strClose)));
 | 
|---|
 | 93 |                                         if (strType == "cdata") xmleLastElement.text += strText.substring(strOpen.length, strText.indexOf(strClose));
 | 
|---|
 | 94 |                                 }
 | 
|---|
 | 95 |                                 if (strText.indexOf(strClose)+ strClose.length < strText.length) {
 | 
|---|
 | 96 |                                         xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText.substring(strText.indexOf(strClose)+ strClose.length, strText.length));
 | 
|---|
 | 97 |                                         if (strType == "cdata") xmleLastElement.text += strText.substring(strText.indexOf(strClose)+ strClose.length, strText.length);
 | 
|---|
 | 98 |                                 }
 | 
|---|
 | 99 |                                 continue;
 | 
|---|
 | 100 |                         }
 | 
|---|
 | 101 |                         if (strText.replace(/ */, "") === "") strText = "";
 | 
|---|
 | 102 |                         if (arrElementsUnparsed[i].substring(1,2) != "/") {
 | 
|---|
 | 103 |                                 if (iElements === 0) {
 | 
|---|
 | 104 |                                         xmleLastElement = this.rootElement = new REXML_XMLElement(strType, strTag,strAttributes,null,strText);
 | 
|---|
 | 105 |                                         iElements++;
 | 
|---|
 | 106 |                                         if (strText !== "") xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText);
 | 
|---|
 | 107 |                                 } else if (arrElementsUnparsed[i].substring(arrElementsUnparsed[i].length-2,arrElementsUnparsed[i].length-1) != "/") {
 | 
|---|
 | 108 |                                         xmleLastElement = xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement(strType, strTag,strAttributes,xmleLastElement,"");
 | 
|---|
 | 109 |                                         iElements++;
 | 
|---|
 | 110 |                                         if (strText !== "") {
 | 
|---|
 | 111 |                                                 xmleLastElement.text += strText;
 | 
|---|
 | 112 |                                                 xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText);
 | 
|---|
 | 113 |                                         }
 | 
|---|
 | 114 |                                 } else {
 | 
|---|
 | 115 |                                         xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement(strType, strTag,strAttributes,xmleLastElement,strText);
 | 
|---|
 | 116 |                                         if (strText !== "") xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText);
 | 
|---|
 | 117 |                                 }
 | 
|---|
 | 118 |                         } else {
 | 
|---|
 | 119 |                                 xmleLastElement = xmleLastElement.parentElement;
 | 
|---|
 | 120 |                                 iElements--;
 | 
|---|
 | 121 |                                 if (xmleLastElement && strText !== "") {
 | 
|---|
 | 122 |                                         xmleLastElement.text += strText;
 | 
|---|
 | 123 |                                         xmleLastElement.childElements[xmleLastElement.childElements.length] = new REXML_XMLElement("text", "","",xmleLastElement,strText);
 | 
|---|
 | 124 |                                 }
 | 
|---|
 | 125 |                         }
 | 
|---|
 | 126 |                 }
 | 
|---|
 | 127 |         }
 | 
|---|
 | 128 | 
 | 
|---|
 | 129 |         function REXML_XMLElement(strType, strName, strAttributes, xmlParent, strText) {
 | 
|---|
 | 130 |                 this.type = strType;
 | 
|---|
 | 131 |                 this.name = strName;
 | 
|---|
 | 132 |                 this.attributeString = strAttributes;
 | 
|---|
 | 133 |                 this.attributes = null;
 | 
|---|
 | 134 |                 this.childElements = [];
 | 
|---|
 | 135 |                 this.parentElement = xmlParent;
 | 
|---|
 | 136 |                 this.text = strText; // text of element
 | 
|---|
 | 137 | 
 | 
|---|
 | 138 |                 this.getText = REXML_XMLElement_getText; // text of element and child elements
 | 
|---|
 | 139 |                 this.childElement = REXML_XMLElement_childElement;
 | 
|---|
 | 140 |                 this.attribute = REXML_XMLElement_attribute;
 | 
|---|
 | 141 |         }
 | 
|---|
 | 142 | 
 | 
|---|
 | 143 |                 function REXML_XMLElement_getText() {
 | 
|---|
 | 144 |                         if (this.type == "text" || this.type == "cdata") {
 | 
|---|
 | 145 |                                 return this.text;
 | 
|---|
 | 146 |                         } else if (this.childElements.length) {
 | 
|---|
 | 147 |                                 var L = "";
 | 
|---|
 | 148 |                                 for (var i=0; i<this.childElements.length; i++) {
 | 
|---|
 | 149 |                                         L += this.childElements[i].getText();
 | 
|---|
 | 150 |                                 }
 | 
|---|
 | 151 |                                 return L;
 | 
|---|
 | 152 |                         } else return "";
 | 
|---|
 | 153 |                 }
 | 
|---|
 | 154 |                 
 | 
|---|
 | 155 |                 function REXML_XMLElement_childElement(strElementName) {
 | 
|---|
 | 156 |                         for (var i=0; i<this.childElements.length; i++) if (this.childElements[i].name == strElementName) return this.childElements[i];
 | 
|---|
 | 157 |                         return null;
 | 
|---|
 | 158 |                 }
 | 
|---|
 | 159 | 
 | 
|---|
 | 160 |                 function REXML_XMLElement_attribute(strAttributeName) {
 | 
|---|
 | 161 |                         if (!this.attributes) {
 | 
|---|
 | 162 |                                 var reAttributes = new RegExp(" ([^= ]*)=","g"); // matches attributes
 | 
|---|
 | 163 |                                 if (this.attributeString.match(reAttributes) && this.attributeString.match(reAttributes).length) {
 | 
|---|
 | 164 |                                         var arrAttributes = this.attributeString.match(reAttributes);
 | 
|---|
 | 165 |                                         if (!arrAttributes.length) arrAttributes = null;
 | 
|---|
 | 166 |                                         else for (var j=0; j<arrAttributes.length; j++) {
 | 
|---|
 | 167 |                                                 arrAttributes[j] = new Array(
 | 
|---|
 | 168 |                                                         (arrAttributes[j]+"").replace(/[= ]/g,""),
 | 
|---|
 | 169 |                                                         ParseAttribute(this.attributeString, (arrAttributes[j]+"").replace(/[= ]/g,""))
 | 
|---|
 | 170 |                                                                                 );
 | 
|---|
 | 171 |                                         }
 | 
|---|
 | 172 |                                         this.attributes = arrAttributes;
 | 
|---|
 | 173 |                                 }
 | 
|---|
 | 174 |                         }
 | 
|---|
 | 175 |                         if (this.attributes) for (var i=0; i<this.attributes.length; i++) if (this.attributes[i][0] == strAttributeName) return this.attributes[i][1];
 | 
|---|
 | 176 |                         return "";
 | 
|---|
 | 177 |                 }
 | 
|---|
 | 178 | 
 | 
|---|
 | 179 | 
 | 
|---|
 | 180 | function JSXMLBuilder() {
 | 
|---|
 | 181 |         this.XML = "";
 | 
|---|
 | 182 |         this.elements = [];
 | 
|---|
 | 183 |         Array.prototype.remove = Array_Remove;
 | 
|---|
 | 184 |         Array.prototype.add = Array_Add;
 | 
|---|
 | 185 | 
 | 
|---|
 | 186 |         this.load = JSXMLBuilder_load;
 | 
|---|
 | 187 |         this.element = JSXMLBuilder_element;
 | 
|---|
 | 188 |         this.addElementAt = JSXMLBuilder_addElementAt;
 | 
|---|
 | 189 |         this.insertElementAt = JSXMLBuilder_insertElementAt;
 | 
|---|
 | 190 |         this.removeElement = JSXMLBuilder_removeElement;
 | 
|---|
 | 191 |         this.generateXML = JSXMLBuilder_generateXML;
 | 
|---|
 | 192 |         this.moveElement = JSXMLBuilder_moveElement;
 | 
|---|
 | 193 | }
 | 
|---|
 | 194 | 
 | 
|---|
 | 195 |         function JSXMLBuilder_load(strXML, xmleElem) {
 | 
|---|
 | 196 |                 this.XML = strXML;
 | 
|---|
 | 197 | 
 | 
|---|
 | 198 |                 if (!xmleElem) {
 | 
|---|
 | 199 |                         if (strXML.length) xmleElem = (new REXML(strXML)).rootElement;
 | 
|---|
 | 200 |                         else return false;
 | 
|---|
 | 201 |                 }
 | 
|---|
 | 202 | 
 | 
|---|
 | 203 |                 var xmlBuilder = new JSXMLIterator(xmleElem);
 | 
|---|
 | 204 | 
 | 
|---|
 | 205 |                 while (true) {
 | 
|---|
 | 206 |                         if (xmlBuilder.xmleElem.type == "element") {
 | 
|---|
 | 207 |                                 if (xmlBuilder.xmleElem.attributes) {
 | 
|---|
 | 208 |                                         this.addElementAt(xmlBuilder.xmleElem.name,xmlBuilder.xmleElem.attributes, xmlBuilder.xmleElem.text, this.elements.length, xmlBuilder.iElemLevel);
 | 
|---|
 | 209 |                                 } else {        
 | 
|---|
 | 210 |                                         this.addElementAt(xmlBuilder.xmleElem.name,xmlBuilder.xmleElem.attributeString, xmlBuilder.xmleElem.text, this.elements.length, xmlBuilder.iElemLevel);
 | 
|---|
 | 211 |                                 }
 | 
|---|
 | 212 |                         }
 | 
|---|
 | 213 |                         if (!xmlBuilder.getNextNode(false)) break;
 | 
|---|
 | 214 |                 }
 | 
|---|
 | 215 |                 for (var i=0; i<this.elements.length; i++) this.elements[i].index = i;
 | 
|---|
 | 216 |         }
 | 
|---|
 | 217 | 
 | 
|---|
 | 218 |         function JSXMLBuilder_element(iIndex) {
 | 
|---|
 | 219 |                 return this.elements[iIndex];
 | 
|---|
 | 220 |         }
 | 
|---|
 | 221 | 
 | 
|---|
 | 222 |         function JSXMLBuilder_addElementAt(strElement,Attributes,strText,iElemIndex,iElemLevel) {
 | 
|---|
 | 223 |                 iElemIndex = parseInt(iElemIndex);
 | 
|---|
 | 224 |                 iElemLevel = parseInt(iElemLevel);
 | 
|---|
 | 225 |                 if (iElemIndex < 0 || typeof(iElemIndex) != "number" || isNaN(iElemIndex)) iElemIndex = (this.elements.length>0) ? this.elements.length-1 : 0;
 | 
|---|
 | 226 |                 if (iElemLevel < 0 || typeof(iElemLevel) != "number" || isNaN(iElemLevel)) iElemLevel = this.elements[iElemIndex-1].level;
 | 
|---|
 | 227 |                 if (!Attributes) Attributes = "";
 | 
|---|
 | 228 |                 var Elem = [];
 | 
|---|
 | 229 |                 var iAddIndex = iElemIndex;
 | 
|---|
 | 230 |                 if (iElemIndex > 0) {
 | 
|---|
 | 231 |                         for (var i=iElemIndex; i<this.elements.length; i++) if (this.elements[i].level > iElemLevel) iAddIndex++;
 | 
|---|
 | 232 |                         else if (this.elements[i].level <= this.elements[iElemIndex].level) break;
 | 
|---|
 | 233 |                         Elem = new JSXMLBuilder_XMLElement(strElement,Attributes,strText,iElemLevel+1,this);
 | 
|---|
 | 234 |                 } else {
 | 
|---|
 | 235 |                         Elem = new JSXMLBuilder_XMLElement(strElement,Attributes,strText,1,this);
 | 
|---|
 | 236 |                 }
 | 
|---|
 | 237 |                 this.elements = this.elements.add(iAddIndex,Elem);
 | 
|---|
 | 238 |                 for (var i=iAddIndex; i<this.elements.length; i++) this.elements[i].index = i;
 | 
|---|
 | 239 |         }
 | 
|---|
 | 240 | 
 | 
|---|
 | 241 |         function JSXMLBuilder_insertElementAt(strElement,Attributes,strText,iElemIndex,iElemLevel) {
 | 
|---|
 | 242 |                 iElemIndex = parseInt(iElemIndex);
 | 
|---|
 | 243 |                 iElemLevel = parseInt(iElemLevel);
 | 
|---|
 | 244 |                 if (iElemIndex < 0 || typeof(iElemIndex) != "number" || isNaN(iElemIndex)) iElemIndex = (this.elements.length>0) ? this.elements.length-1 : 0;
 | 
|---|
 | 245 |                 if (iElemLevel < 0 || typeof(iElemLevel) != "number" || isNaN(iElemLevel)) iElemLevel = this.elements[iElemIndex-1].level;
 | 
|---|
 | 246 |                 if (!Attributes) Attributes = "";
 | 
|---|
 | 247 |                 var Elem = null;
 | 
|---|
 | 248 |                 var iAddIndex = iElemIndex;
 | 
|---|
 | 249 |                 if (iElemIndex > 0 && iElemLevel > 0) {
 | 
|---|
 | 250 |                         Elem = new JSXMLBuilder_XMLElement(strElement,Attributes,strText,iElemLevel+1,this);
 | 
|---|
 | 251 |                 } else {
 | 
|---|
 | 252 |                         Elem = new JSXMLBuilder_XMLElement(strElement,Attributes,strText,1,this);
 | 
|---|
 | 253 |                 }
 | 
|---|
 | 254 |                 this.elements = this.elements.add(iAddIndex,Elem);
 | 
|---|
 | 255 |                 for (var i=iAddIndex; i<this.elements.length; i++) this.elements[i].index = i;
 | 
|---|
 | 256 |         }
 | 
|---|
 | 257 | 
 | 
|---|
 | 258 | 
 | 
|---|
 | 259 |         function JSXMLBuilder_removeElement(iElemIndex) {
 | 
|---|
 | 260 |                 iElemIndex = parseInt(iElemIndex);
 | 
|---|
 | 261 |                 for (var iAfterElem=iElemIndex+1; iAfterElem<this.elements.length; iAfterElem++) if (this.elements[iAfterElem].level < this.elements[iElemIndex].level+1) break;
 | 
|---|
 | 262 | 
 | 
|---|
 | 263 |                 this.elements = this.elements.slice(0,iElemIndex).concat(this.elements.slice(iAfterElem,this.elements.length));
 | 
|---|
 | 264 |                 for (var i=iElemIndex; i<this.elements.length; i++) this.elements[i].index = i;
 | 
|---|
 | 265 |         }
 | 
|---|
 | 266 | 
 | 
|---|
 | 267 |         function JSXMLBuilder_moveElement(iElem1Index,iElem2Index) {
 | 
|---|
 | 268 |                 var arrElem1Elements = new Array(this.elements[iElem1Index]);
 | 
|---|
 | 269 |                 var arrElem2Elements = new Array(this.elements[iElem2Index]);
 | 
|---|
 | 270 |                 for (var i=iElem1Index; i<this.elements.length; i++) if (this.elements[i].level > this.elements[iElem1Index].level) arrElem1Elements[arrElem1Elements.length] = this.elements[i]; else if (i>iElem1Index) break;
 | 
|---|
 | 271 |                 for (var i=iElem2Index; i<this.elements.length; i++) if (this.elements[i].level > this.elements[iElem2Index].level) arrElem2Elements[arrElem2Elements.length] = this.elements[i]; else if (i>iElem2Index) break;
 | 
|---|
 | 272 |                 var arrMovedElements = [];
 | 
|---|
 | 273 |                 if (iElem1Index < iElem2Index) {
 | 
|---|
 | 274 |                         for (i=0; i<iElem1Index; i++) arrMovedElements[arrMovedElements.length] = this.elements[i]; // start to the 1st element
 | 
|---|
 | 275 |                         for (i=iElem1Index+arrElem1Elements.length; i<iElem2Index+arrElem2Elements.length; i++) arrMovedElements[arrMovedElements.length] = this.elements[i]; // end of 1st element to end of 2nd element
 | 
|---|
 | 276 |                         for (i=0; i<arrElem1Elements.length; i++) arrMovedElements[arrMovedElements.length] = arrElem1Elements[i]; // 1st element and all child elements
 | 
|---|
 | 277 |                         for (i=iElem2Index+arrElem2Elements.length; i<this.elements.length; i++) arrMovedElements[arrMovedElements.length] = this.elements[i]; // end of 2nd element to end
 | 
|---|
 | 278 |                         this.elements = arrMovedElements;
 | 
|---|
 | 279 |                 } else {
 | 
|---|
 | 280 |                         for (i=0; i<iElem2Index; i++) arrMovedElements[arrMovedElements.length] = this.elements[i]; // start to the 2nd element
 | 
|---|
 | 281 |                         for (i=0; i<arrElem1Elements.length; i++) arrMovedElements[arrMovedElements.length] = arrElem1Elements[i]; // 1st element and all child elements
 | 
|---|
 | 282 |                         for (i=iElem2Index; i<iElem1Index; i++) arrMovedElements[arrMovedElements.length] = this.elements[i]; // 2nd element to 1st element
 | 
|---|
 | 283 |                         for (i=iElem1Index+arrElem1Elements.length; i<this.elements.length; i++) arrMovedElements[arrMovedElements.length] = this.elements[i]; // end of 1st element to end
 | 
|---|
 | 284 |                         this.elements = arrMovedElements;
 | 
|---|
 | 285 |                 }
 | 
|---|
 | 286 |                 for (var i=0; i<this.elements.length; i++) this.elements[i].index = i;
 | 
|---|
 | 287 |         }
 | 
|---|
 | 288 | 
 | 
|---|
 | 289 | 
 | 
|---|
 | 290 |         function JSXMLBuilder_generateXML(bXMLTag) {
 | 
|---|
 | 291 |                 var strXML = "";
 | 
|---|
 | 292 |                 var arrXML = [];
 | 
|---|
 | 293 |                 if (bXMLTag) strXML += '<?xml version="1.0"?>\n\n';
 | 
|---|
 | 294 |                 for (var i=0; i<this.elements.length; i++) {
 | 
|---|
 | 295 |                         strXML += RepeatChar("\t",this.elements[i].level-1);
 | 
|---|
 | 296 |                         strXML += "<" + this.element(i).name; // open tag
 | 
|---|
 | 297 |                         if (this.element(i).attributes) {
 | 
|---|
 | 298 |                                 for (var j=0; j<this.element(i).attributes.length; j++) { // set attributes
 | 
|---|
 | 299 |                                         if (this.element(i).attributes[j]) {
 | 
|---|
 | 300 |                                                 strXML += ' ' + this.element(i).attributes[j][0] + '="' + this.element(i).attributes[j][1] + '"';
 | 
|---|
 | 301 |                                         }
 | 
|---|
 | 302 |                                 }
 | 
|---|
 | 303 |                         } else strXML += this.element(i).attributeString.replace(/[\/>]$/gi, "");
 | 
|---|
 | 304 |                         if (((this.elements[i+1] && this.elements[i+1].level <= this.elements[i].level) || // next element is a lower or equal to
 | 
|---|
 | 305 |                                 (!this.elements[i+1] && this.elements[i-1])) // no next element, previous element
 | 
|---|
 | 306 |                                 && this.element(i).text === "") {
 | 
|---|
 | 307 |                                 strXML += "/";
 | 
|---|
 | 308 |                         }
 | 
|---|
 | 309 |                         strXML += ">";
 | 
|---|
 | 310 |                         if (this.element(i).text !== "") strXML += this.element(i).text;
 | 
|---|
 | 311 |                         else strXML += "\n";
 | 
|---|
 | 312 |                         if (((this.elements[i+1] && this.elements[i+1].level <= this.elements[i].level) || // next element is a lower or equal to
 | 
|---|
 | 313 |                                 (!this.elements[i+1] && this.elements[i-1])) // no next element, previous element
 | 
|---|
 | 314 |                                 && this.element(i).text !== "") strXML += "</" + this.element(i).name + ">\n";
 | 
|---|
 | 315 |                         if (!this.elements[i+1]) {
 | 
|---|
 | 316 |                                 var lastelem = i;
 | 
|---|
 | 317 |                                 for (var j=i; j>-1; j--) {
 | 
|---|
 | 318 |                                         if (this.elements[j].level >= this.elements[i].level) continue;
 | 
|---|
 | 319 |                                         else {
 | 
|---|
 | 320 |                                                 if (this.elements[j].level < this.elements[lastelem].level) {
 | 
|---|
 | 321 |                                                         strXML += RepeatChar("\t",this.elements[j].level-1) + "</" + this.element(j).name + ">\n";
 | 
|---|
 | 322 |                                                         lastelem = j;
 | 
|---|
 | 323 |                                                 }
 | 
|---|
 | 324 |                                         }
 | 
|---|
 | 325 |                                 }
 | 
|---|
 | 326 |                         } else {
 | 
|---|
 | 327 |                                 if (this.elements[i+1].level < this.elements[i].level) {
 | 
|---|
 | 328 |                                         var lastelem = i;
 | 
|---|
 | 329 |                                         for (var j=i; this.elements[j].level>=this.elements[i+1].level; j--) {
 | 
|---|
 | 330 |                                                 if (this.elements[i] && this.elements[j] && this.elements[j].level < this.elements[i].level && this.elements[j].level < this.elements[lastelem].level) {
 | 
|---|
 | 331 |                                                         strXML += RepeatChar("\t",this.elements[j].level-1) + "</" + this.element(j).name + ">\n";
 | 
|---|
 | 332 |                                                         lastelem = j;
 | 
|---|
 | 333 |                                                 }
 | 
|---|
 | 334 |                                         }
 | 
|---|
 | 335 |                                 }
 | 
|---|
 | 336 |                         }
 | 
|---|
 | 337 |                         if (strXML.length > 1000) {
 | 
|---|
 | 338 |                                 arrXML[arrXML.length] = strXML;
 | 
|---|
 | 339 |                                 strXML = "";
 | 
|---|
 | 340 |                         }
 | 
|---|
 | 341 |                 }
 | 
|---|
 | 342 |                 arrXML[arrXML.length] = strXML;
 | 
|---|
 | 343 |                 return arrXML.join("");
 | 
|---|
 | 344 |         }
 | 
|---|
 | 345 | 
 | 
|---|
 | 346 |         function JSXMLBuilder_XMLElement(strName,Attributes,strText,iLevel,xmlBuilder) {
 | 
|---|
 | 347 |                 this.type = "element";
 | 
|---|
 | 348 |                 this.name = strName;
 | 
|---|
 | 349 |                 this.attributes = (typeof(Attributes) != "string") ? Attributes : null;
 | 
|---|
 | 350 |                 this.attributeString = (typeof(Attributes) == "string") ? Attributes : "";
 | 
|---|
 | 351 |                 this.text = strText;
 | 
|---|
 | 352 |                 this.level = iLevel;
 | 
|---|
 | 353 |                 this.index = -1;
 | 
|---|
 | 354 |                 this.xmlBuilder = xmlBuilder;
 | 
|---|
 | 355 | 
 | 
|---|
 | 356 |                 this.parseAttributes = JSXMLBuilder_XMLElement_parseAttributes;
 | 
|---|
 | 357 |                 this.attribute = JSXMLBuilder_XMLElement_attribute;
 | 
|---|
 | 358 |                 this.setAttribute = JSXMLBuilder_XMLElement_setAttribute;
 | 
|---|
 | 359 |                 this.removeAttribute = JSXMLBuilder_XMLElement_removeAttribute;
 | 
|---|
 | 360 |                 this.parentElement = JSXMLBuilder_XMLElement_parentElement;
 | 
|---|
 | 361 |                 this.childElement = JSXMLBuilder_XMLElement_childElement;
 | 
|---|
 | 362 |         }
 | 
|---|
 | 363 | 
 | 
|---|
 | 364 |                 function JSXMLBuilder_XMLElement_parseAttributes() {
 | 
|---|
 | 365 |                         if (!this.attributes) {
 | 
|---|
 | 366 |                                 var reAttributes = new RegExp(" ([^= ]*)=","g"); // matches attributes
 | 
|---|
 | 367 |                                 if (this.attributeString.match(reAttributes) && this.attributeString.match(reAttributes).length) {
 | 
|---|
 | 368 |                                         var arrAttributes = this.attributeString.match(reAttributes);
 | 
|---|
 | 369 |                                         if (!arrAttributes.length) arrAttributes = null;
 | 
|---|
 | 370 |                                         else for (var j=0; j<arrAttributes.length; j++) {
 | 
|---|
 | 371 |                                                 arrAttributes[j] = new Array(
 | 
|---|
 | 372 |                                                         (arrAttributes[j]+"").replace(/[= ]/g,""),
 | 
|---|
 | 373 |                                                         ParseAttribute(this.attributeString, (arrAttributes[j]+"").replace(/[= ]/g,""))
 | 
|---|
 | 374 |                                                                                 );
 | 
|---|
 | 375 |                                         }
 | 
|---|
 | 376 |                                         this.attributes = arrAttributes;
 | 
|---|
 | 377 |                                 }
 | 
|---|
 | 378 |                         }
 | 
|---|
 | 379 |                 }
 | 
|---|
 | 380 |         
 | 
|---|
 | 381 |                 function JSXMLBuilder_XMLElement_attribute(AttributeName) {
 | 
|---|
 | 382 |                         if (!this.attributes) this.parseAttributes();
 | 
|---|
 | 383 |                         if (this.attributes) for (var i=0; i<this.attributes.length; i++) if (this.attributes[i][0] == AttributeName) return this.attributes[i][1];
 | 
|---|
 | 384 |                         return "";
 | 
|---|
 | 385 |                 }
 | 
|---|
 | 386 | 
 | 
|---|
 | 387 |                 function JSXMLBuilder_XMLElement_setAttribute(AttributeName,Value) {
 | 
|---|
 | 388 |                         if (!this.attributes) this.parseAttributes();
 | 
|---|
 | 389 |                         if (this.attributes) for (var i=0; i<this.attributes.length; i++) if (this.attributes[i][0] == AttributeName) {
 | 
|---|
 | 390 |                                 this.attributes[i][1] = Value;
 | 
|---|
 | 391 |                                 return;
 | 
|---|
 | 392 |                         }
 | 
|---|
 | 393 |                         this.attributes[this.attributes.length] = new Array(AttributeName,Value);
 | 
|---|
 | 394 |                 }
 | 
|---|
 | 395 | 
 | 
|---|
 | 396 |                 function JSXMLBuilder_XMLElement_removeAttribute(AttributeName,Value) {
 | 
|---|
 | 397 |                         if (!this.attributes) this.parseAttributes();
 | 
|---|
 | 398 |                         if (this.attributes) for (var i=0; i<this.attributes.length; i++) if (this.attributes[i][0] == AttributeName) {
 | 
|---|
 | 399 |                                 this.attributes = this.attributes.remove(i);
 | 
|---|
 | 400 |                                 return;
 | 
|---|
 | 401 |                         }
 | 
|---|
 | 402 |                 }
 | 
|---|
 | 403 | 
 | 
|---|
 | 404 |                 function JSXMLBuilder_XMLElement_parentElement() {
 | 
|---|
 | 405 |                         for (var i=this.index; this.xmlBuilder.element(i) && this.xmlBuilder.element(i).level != this.level-1; i--);
 | 
|---|
 | 406 |                         return this.xmlBuilder.element(i);
 | 
|---|
 | 407 |                 }
 | 
|---|
 | 408 | 
 | 
|---|
 | 409 |                 function JSXMLBuilder_XMLElement_childElement(Child) {
 | 
|---|
 | 410 |                         var iFind = -1;
 | 
|---|
 | 411 |                         for (var i=this.index+1; i<this.xmlBuilder.elements.length; i++) {
 | 
|---|
 | 412 |                                 if (this.xmlBuilder.elements[i].level == this.level+1) {
 | 
|---|
 | 413 |                                         iFind++;
 | 
|---|
 | 414 |                                         if (iFind == Child || this.xmlBuilder.elements[i].name == Child) return this.xmlBuilder.elements[i];
 | 
|---|
 | 415 |                                 } else if (this.xmlBuilder.elements[i].level <= this.level) break;
 | 
|---|
 | 416 |                         }
 | 
|---|
 | 417 |                         return null;
 | 
|---|
 | 418 |                 }
 | 
|---|
 | 419 | 
 | 
|---|
 | 420 | 
 | 
|---|
 | 421 | function JSXMLIterator(xmleElem) {
 | 
|---|
 | 422 |         this.xmleElem = xmleElem;
 | 
|---|
 | 423 |         
 | 
|---|
 | 424 |         this.iElemIndex = 0;
 | 
|---|
 | 425 |         this.arrElemIndex = new Array(0);
 | 
|---|
 | 426 |         this.iElemLevel = 0;
 | 
|---|
 | 427 |         this.iElem = 0;
 | 
|---|
 | 428 |         this.arrElemIndex[this.iElemLevel] = -1;
 | 
|---|
 | 429 | 
 | 
|---|
 | 430 |         this.getNextNode = JSXMLIterator_getNextNode;
 | 
|---|
 | 431 | }
 | 
|---|
 | 432 | 
 | 
|---|
 | 433 |         function JSXMLIterator_getNextNode() {
 | 
|---|
 | 434 |                 if (!this.xmleElem || this.iElemLevel<0)        return false;
 | 
|---|
 | 435 |                 if (this.xmleElem.childElements.length) {  // move up
 | 
|---|
 | 436 |                         this.arrElemIndex[this.iElemLevel]++;
 | 
|---|
 | 437 |                         this.iElemIndex++;
 | 
|---|
 | 438 |                         this.iElemLevel++;
 | 
|---|
 | 439 |                         this.arrElemIndex[this.iElemLevel] = 0;
 | 
|---|
 | 440 |                         this.xmleElem = this.xmleElem.childElements[0];
 | 
|---|
 | 441 |                 } else { // move next
 | 
|---|
 | 442 |                         this.iElemIndex++;
 | 
|---|
 | 443 |                         this.arrElemIndex[this.iElemLevel]++;
 | 
|---|
 | 444 |                         if (this.xmleElem.parentElement && this.xmleElem.parentElement.childElements.length && this.arrElemIndex[this.iElemLevel] < this.xmleElem.parentElement.childElements.length) this.xmleElem = this.xmleElem.parentElement.childElements[this.arrElemIndex[this.iElemLevel]];
 | 
|---|
 | 445 |                         else {
 | 
|---|
 | 446 |                                 if (this.iElemLevel>0) { // move down
 | 
|---|
 | 447 |                                         for (; this.iElemLevel > 0; this.iElemLevel--) {
 | 
|---|
 | 448 |                                                 if (this.xmleElem.parentElement && this.xmleElem.parentElement.childElements[this.arrElemIndex[this.iElemLevel]]) {
 | 
|---|
 | 449 |                                                         this.xmleElem = this.xmleElem.parentElement.childElements[this.arrElemIndex[this.iElemLevel]];
 | 
|---|
 | 450 |                                                         this.iElemLevel++;
 | 
|---|
 | 451 |                                                         this.arrElemIndex = this.arrElemIndex.slice(0,this.iElemLevel+1);
 | 
|---|
 | 452 |                                                         break;
 | 
|---|
 | 453 |                                                 } else {
 | 
|---|
 | 454 |                                                         this.xmleElem = this.xmleElem.parentElement;
 | 
|---|
 | 455 |                                                 }
 | 
|---|
 | 456 |                                         }
 | 
|---|
 | 457 |                                         this.iElemLevel--;
 | 
|---|
 | 458 |                                 } else {
 | 
|---|
 | 459 |                                         return false;
 | 
|---|
 | 460 |                                 }
 | 
|---|
 | 461 |                         }
 | 
|---|
 | 462 |                 }
 | 
|---|
 | 463 |                 return (typeof(this.xmleElem) == "object" && this.iElemLevel > -1);
 | 
|---|
 | 464 |         }
 | 
|---|
 | 465 | 
 | 
|---|
 | 466 | function ParseAttribute(str,Attribute) {
 | 
|---|
 | 467 |         var str = str +  ">";
 | 
|---|
 | 468 |         if (str.indexOf(Attribute + "='")>-1) var Attr = new RegExp(".*" + Attribute + "='([^']*)'.*>");
 | 
|---|
 | 469 |         else if (str.indexOf(Attribute + '="')>-1) var Attr = new RegExp(".*" + Attribute + '="([^"]*)".*>');
 | 
|---|
 | 470 |         return str.replace(Attr, "$1");
 | 
|---|
 | 471 | }
 | 
|---|
 | 472 | 
 | 
|---|
 | 473 | function Array_Remove(c) {
 | 
|---|
 | 474 |         var tmparr = [];
 | 
|---|
 | 475 |         for (var i=0; i<this.length; i++) if (i!=c) tmparr[tmparr.length] = this[i];
 | 
|---|
 | 476 |         return tmparr;
 | 
|---|
 | 477 | }
 | 
|---|
 | 478 | 
 | 
|---|
 | 479 | function Array_Add(c, cont) {
 | 
|---|
 | 480 |         if (c == this.length) {
 | 
|---|
 | 481 |                 this[this.length] = cont;
 | 
|---|
 | 482 |                 return this;
 | 
|---|
 | 483 |         }
 | 
|---|
 | 484 |         var tmparr = [];
 | 
|---|
 | 485 |         for (var i=0; i<this.length; i++) {
 | 
|---|
 | 486 |                 if (i==c) tmparr[tmparr.length] = cont;
 | 
|---|
 | 487 |                 tmparr[tmparr.length] = this[i];
 | 
|---|
 | 488 |         }
 | 
|---|
 | 489 |         if (!tmparr[c]) tmparr[c] = cont;
 | 
|---|
 | 490 |         return tmparr;
 | 
|---|
 | 491 | }
 | 
|---|
 | 492 | 
 | 
|---|
 | 493 | function RepeatChar(sChar,iNum) {
 | 
|---|
 | 494 |         var L = "";
 | 
|---|
 | 495 |         for (var i=0; i<iNum; i++) L += sChar;
 | 
|---|
 | 496 |         return L;
 | 
|---|
 | 497 | }
 | 
|---|