| 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 | } |