1 /** 2 * ==================================================================== 3 * About 4 * ==================================================================== 5 * Sarissa cross browser XML library 6 * @version 0.9.5.2 7 * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net 8 * 9 * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs. 10 * The library supports Gecko based browsers like Mozilla and Firefox, 11 * Internet Explorer (5.5+ with MSXML3.0+) and, last but not least, KHTML based browsers like 12 * Konqueror and Safari. 13 * 14 * ==================================================================== 15 * Licence 16 * ==================================================================== 17 * This program is free software; you can redistribute it and/or modify 18 * it under the terms of the GNU General Public License version 2 or 19 * the GNU Lesser General Public License version 2.1 as published by 20 * the Free Software Foundation (your choice of the two). 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License or GNU Lesser General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * or GNU Lesser General Public License along with this program; if not, 29 * write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 30 * or visit http://www.gnu.org 31 * 32 */ 33 /** 34 * <p>Sarissa is a utility class. Provides static methods for DOMDocument and 35 * XMLHTTP objects, DOM Node serializatrion to XML strings and other goodies.</p> 36 * @constructor 37 */ 38 function Sarissa(){}; 39 /** @private */ 40 Sarissa.PARSED_OK = "Document contains no parsing errors"; 41 /** 42 * Tells you whether transformNode and transformNodeToObject are available. This functionality 43 * is contained in sarissa_ieemu_xslt.js and is deprecated. If you want to control XSLT transformations 44 * use the XSLTProcessor 45 * @deprecated 46 * @type boolean 47 */ 48 Sarissa.IS_ENABLED_TRANSFORM_NODE = false; 49 /** 50 * tells you whether XMLHttpRequest (or equivalent) is available 51 * @type boolean 52 */ 53 Sarissa.IS_ENABLED_XMLHTTP = false; 54 /** 55 * <b>Deprecated, will be removed in 0.9.6</b>. Check for 56 * <code>window.XSLTProcessor</code> instead to see if 57 * XSLTProcessor is available. 58 * @type boolean 59 */ 60 Sarissa.IS_ENABLED_XSLTPROC = false; 61 /** 62 * tells you whether selectNodes/selectSingleNode is available 63 * @type boolean 64 */ 65 Sarissa.IS_ENABLED_SELECT_NODES = false; 66 var _sarissa_iNsCounter = 0; 67 var _SARISSA_IEPREFIX4XSLPARAM = ""; 68 var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true; 69 var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument; 70 var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature; 71 /** <b>Deprecated, will be removed in 0.9.6</b>. @deprecated */ 72 var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE; 73 /** <b>Deprecated, will be removed in 0.9.6</b>. @deprecated */ 74 var _SARISSA_IS_IE = document.all && window.ActiveXObject && (navigator.userAgent.toLowerCase().indexOf("msie") > -1); 75 //========================================== 76 // Implement Node constants if not available 77 //========================================== 78 if(!window.Node || !window.Node.ELEMENT_NODE){ 79 var Node = {ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5, ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12}; 80 }; 81 // IE initialization 82 if(_SARISSA_IS_IE){ 83 // for XSLT parameter names, prefix needed by IE 84 _SARISSA_IEPREFIX4XSLPARAM = "xsl:"; 85 // used to store the most recent ProgID available out of the above 86 var _SARISSA_DOM_PROGID = ""; 87 var _SARISSA_XMLHTTP_PROGID = ""; 88 /** 89 * Called when the Sarissa_xx.js file is parsed, to pick most recent 90 * ProgIDs for IE, then gets destroyed. 91 * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object 92 * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled 93 */ 94 function pickRecentProgID(idList, enabledList){ 95 // found progID flag 96 var bFound = false; 97 for(var i=0; i < idList.length && !bFound; i++){ 98 try{ 99 var oDoc = new ActiveXObject(idList[i]); 100 o2Store = idList[i]; 101 bFound = true; 102 for(var j=0;j<enabledList.length;j++) 103 if(i <= enabledList[j][1]) 104 Sarissa["IS_ENABLED_"+enabledList[j][0]] = true; 105 }catch (objException){ 106 // trap; try next progID 107 }; 108 }; 109 if (!bFound) 110 throw "Could not retreive a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")"; 111 idList = null; 112 return o2Store; 113 }; 114 // pick best available MSXML progIDs 115 _SARISSA_DOM_PROGID = pickRecentProgID(["Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"], [["SELECT_NODES", 2],["TRANSFORM_NODE", 2]]); 116 _SARISSA_XMLHTTP_PROGID = pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], [["XMLHTTP", 4]]); 117 _SARISSA_THREADEDDOM_PROGID = pickRecentProgID(["Msxml2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]); 118 _SARISSA_XSLTEMPLATE_PROGID = pickRecentProgID(["Msxml2.XSLTemplate.5.0", "Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"], [["XSLTPROC", 2]]); 119 // we dont need this anymore 120 pickRecentProgID = null; 121 //============================================ 122 // Factory methods (IE) 123 //============================================ 124 // see non-IE version 125 Sarissa.getDomDocument = function(sUri, sName){ 126 var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID); 127 // if a root tag name was provided, we need to load it in the DOM 128 // object 129 if (sName){ 130 // if needed, create an artifical namespace prefix the way Moz 131 // does 132 if (sUri){ 133 oDoc.loadXML("<a" + _sarissa_iNsCounter + ":" + sName + " xmlns:a" + _sarissa_iNsCounter + "=\"" + sUri + "\" />"); 134 // don't use the same prefix again 135 ++_sarissa_iNsCounter; 136 } 137 else 138 oDoc.loadXML("<" + sName + "/>"); 139 }; 140 return oDoc; 141 }; 142 if(!window.XMLHttpRequest){ 143 /** 144 * Emulate XMLHttpRequest 145 * @constructor 146 */ 147 function XMLHttpRequest(){ 148 return new ActiveXObject(_SARISSA_XMLHTTP_PROGID); 149 }; 150 }; 151 // see non-IE version 152 Sarissa.getParseErrorText = function (oDoc) { 153 var parseErrorText = Sarissa.PARSED_OK; 154 if(oDoc.parseError != 0){ 155 parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason + 156 "\nLocation: " + oDoc.parseError.url + 157 "\nLine Number " + oDoc.parseError.line + ", Column " + 158 oDoc.parseError.linepos + 159 ":\n" + oDoc.parseError.srcText + 160 "\n"; 161 for(var i = 0; i < oDoc.parseError.linepos;i++){ 162 parseErrorText += "-"; 163 }; 164 parseErrorText += "^\n"; 165 }; 166 return parseErrorText; 167 }; 168 // see non-IE version 169 Sarissa.setXpathNamespaces = function(oDoc, sNsSet) { 170 oDoc.setProperty("SelectionLanguage", "XPath"); 171 oDoc.setProperty("SelectionNamespaces", sNsSet); 172 }; 173 /** 174 * Basic implementation of Mozilla's XSLTProcessor for IE. 175 * Reuses the same XSLT stylesheet for multiple transforms 176 * @constructor 177 */ 178 function XSLTProcessor(){ 179 this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID); 180 this.processor = null; 181 }; 182 /** 183 * Impoprts the given XSLT DOM and compiles it to a reusable transform 184 * @argument xslDoc The XSLT DOMDocument to import 185 */ 186 XSLTProcessor.prototype.importStylesheet = function(xslDoc){ 187 // convert stylesheet to free threaded 188 var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID); 189 converted.loadXML(xslDoc.xml); 190 this.template.stylesheet = converted; 191 this.processor = this.template.createProcessor(); 192 // (re)set default param values 193 this.paramsSet = new Array(); 194 }; 195 /** 196 * Transform the given XML DOM 197 * @argument sourceDoc The XML DOMDocument to transform 198 * @return The transformation result as a DOM Document 199 */ 200 XSLTProcessor.prototype.transformToDocument = function(sourceDoc){ 201 this.processor.input = sourceDoc; 202 var outDoc = new ActiveXObject(_SARISSA_DOM_PROGID); 203 this.processor.output = outDoc; 204 this.processor.transform(); 205 return outDoc; 206 }; 207 /** 208 * Not sure if this works in IE. Maybe this will allow non-well-formed 209 * transformation results (i.e. with no single root element) 210 * @argument sourceDoc The XML DOMDocument to transform 211 * @return The transformation result as a DOM Fragment 212 */ 213 XSLTProcessor.prototype.transformToFragment = function(sourceDoc, ownerDocument){ 214 return this.transformToDocument(sourceDoc); 215 }; 216 /** 217 * Set global XSLT parameter of the imported stylesheet 218 * @argument nsURI The parameter namespace URI 219 * @argument name The parameter base name 220 * @argument value The new parameter value 221 */ 222 XSLTProcessor.prototype.setParameter = function(nsURI, name, value){ 223 /* nsURI is optional but cannot be null */ 224 if(nsURI){ 225 this.processor.addParameter(name, value, nsURI); 226 }else{ 227 this.processor.addParameter(name, value); 228 }; 229 /* update updated params for getParameter */ 230 if(!this.paramsSet[""+nsURI]){ 231 this.paramsSet[""+nsURI] = new Array(); 232 }; 233 this.paramsSet[""+nsURI][name] = value; 234 }; 235 /** 236 * Gets a parameter if previously set by setParameter. Returns null 237 * otherwise 238 * @argument name The parameter base name 239 * @argument value The new parameter value 240 * @return The parameter value if reviously set by setParameter, null otherwise 241 */ 242 XSLTProcessor.prototype.getParameter = function(nsURI, name){ 243 if(this.paramsSet[""+nsURI] && this.paramsSet[""+nsURI][name]) 244 return this.paramsSet[""+nsURI][name]; 245 else 246 return null; 247 }; 248 } 249 else{ /* end IE initialization, try to deal with real browsers now ;-) */ 250 if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){ 251 if(window.XMLDocument){ 252 /** 253 * <p>Emulate IE's onreadystatechange attribute</p> 254 */ 255 XMLDocument.prototype.onreadystatechange = null; 256 /** 257 * <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p> 258 * <ul><li>1 == LOADING,</li> 259 * <li>2 == LOADED,</li> 260 * <li>3 == INTERACTIVE,</li> 261 * <li>4 == COMPLETED</li></ul> 262 */ 263 XMLDocument.prototype.readyState = 0; 264 /** 265 * <p>Emulate IE's parseError attribute</p> 266 */ 267 XMLDocument.prototype.parseError = 0; 268 269 // NOTE: setting async to false will only work with documents 270 // called over HTTP (meaning a server), not the local file system, 271 // unless you are using Moz 1.4+. 272 // BTW the try>catch block is for 1.4; I haven't found a way to check if 273 // the property is implemented without 274 // causing an error and I dont want to use user agent stuff for that... 275 var _SARISSA_SYNC_NON_IMPLEMENTED = false; 276 try{ 277 /** 278 * <p>Emulates IE's async property for Moz versions prior to 1.4. 279 * It controls whether loading of remote XML files works 280 * synchronously or asynchronously.</p> 281 */ 282 XMLDocument.prototype.async = true; 283 _SARISSA_SYNC_NON_IMPLEMENTED = true; 284 }catch(e){/* trap */}; 285 /** 286 * <p>Keeps a handle to the original load() method. Internal use and only 287 * if Mozilla version is lower than 1.4</p> 288 * @private 289 */ 290 XMLDocument.prototype._sarissa_load = XMLDocument.prototype.load; 291 292 /** 293 * <p>Overrides the original load method to provide synchronous loading for 294 * Mozilla versions prior to 1.4, using an XMLHttpRequest object (if 295 * async is set to false)</p> 296 * @returns the DOM Object as it was before the load() call (may be empty) 297 */ 298 XMLDocument.prototype.load = function(sURI) { 299 var oDoc = document.implementation.createDocument("", "", null); 300 Sarissa.copyChildNodes(this, oDoc); 301 this.parseError = 0; 302 Sarissa.__setReadyState__(this, 1); 303 try { 304 if(this.async == false && _SARISSA_SYNC_NON_IMPLEMENTED) { 305 var tmp = new XMLHttpRequest(); 306 tmp.open("GET", sURI, false); 307 tmp.send(null); 308 Sarissa.__setReadyState__(this, 2); 309 Sarissa.copyChildNodes(tmp.responseXML, this); 310 Sarissa.__setReadyState__(this, 3); 311 } 312 else { 313 this._sarissa_load(sURI); 314 }; 315 } 316 catch (objException) { 317 this.parseError = -1; 318 } 319 finally { 320 if(this.async == false){ 321 Sarissa.__handleLoad__(this); 322 }; 323 }; 324 return oDoc; 325 }; 326 327 if(window.DOMParser && !XMLDocument.loadXML){ 328 /** 329 * <p>Parses the String given as parameter to build the document content 330 * for the object, exactly like IE's loadXML()</p> 331 * @argument strXML The XML String to load as the Document's childNodes 332 * @returns the old Document structure serialized as an XML String 333 */ 334 XMLDocument.prototype.loadXML = function(strXML){ 335 Sarissa.__setReadyState__(this, 1); 336 var sOldXML = this.xml; 337 var oDoc = (new DOMParser()).parseFromString(strXML, "text/xml"); 338 Sarissa.__setReadyState__(this, 2); 339 Sarissa.copyChildNodes(oDoc, this); 340 Sarissa.__setReadyState__(this, 3); 341 Sarissa.__handleLoad__(this); 342 return sOldXML; 343 }; 344 };//if(window.DOMParser && !XMLDocument.loadXML) 345 };//if(window.XMLDocument) 346 347 /** 348 * <p>Ensures the document was loaded correctly, otherwise sets the 349 * parseError to -1 to indicate something went wrong. Internal use</p> 350 * @private 351 */ 352 Sarissa.__handleLoad__ = function(oDoc){ 353 if (!oDoc.documentElement || oDoc.documentElement.tagName == "parsererror") 354 oDoc.parseError = -1; 355 Sarissa.__setReadyState__(oDoc, 4); 356 }; 357 /** 358 * <p>Attached by an event handler to the load event. Internal use.</p> 359 * @private 360 */ 361 function _sarissa_XMLDocument_onload() { 362 Sarissa.__handleLoad__(this); 363 }; 364 /** 365 * <p>Sets the readyState property of the given DOM Document object. 366 * Internal use.</p> 367 * @private 368 * @argument oDoc the DOM Document object to fire the 369 * readystatechange event 370 * @argument iReadyState the number to change the readystate property to 371 */ 372 Sarissa.__setReadyState__ = function(oDoc, iReadyState){ 373 oDoc.readyState = iReadyState; 374 if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function") 375 oDoc.onreadystatechange(); 376 }; 377 /** 378 * <p>Factory method to obtain a new DOM Document object</p> 379 * @argument sUri the namespace of the root node (if any) 380 * @argument sUri the local name of the root node (if any) 381 * @returns a new DOM Document 382 */ 383 Sarissa.getDomDocument = function(sUri, sName){ 384 var oDoc = document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null); 385 oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false); 386 return oDoc; 387 }; 388 };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT) 389 }; 390 //========================================== 391 // Common stuff 392 //========================================== 393 if(window.XMLHttpRequest){ 394 /** 395 * <p><b>Deprecated, will be removed in 0.9.6</b>. Factory method to obtain a new XMLHTTP Request object</p> 396 * @returns a new XMLHTTP Request object 397 * @deprecated 398 */ 399 Sarissa.getXmlHttpRequest = function() { 400 return new XMLHttpRequest(); 401 }; 402 Sarissa.IS_ENABLED_XMLHTTP = true; 403 }; 404 if(!window.document.importNode){ 405 /** 406 * Implements importNode for the current window document in IE using innerHTML. 407 * Testing showed that DOM was multiple times slower than innerHTML for this, 408 * sorry folks. If you encounter trouble (who knows what IE does behind innerHTML) 409 * please gimme a call. 410 * @param oNode the Node to import 411 * @param bChildren whether to include the children of oNode 412 * @returns the imported node for further use 413 */ 414 window.document.importNode = function(oNode, bChildren){ 415 var importNode = document.createElement("div"); 416 if(bChildren) 417 importNode.innerHTML = Sarissa.serialize(oNode); 418 else 419 importNode.innerHTML = Sarissa.serialize(oNode.cloneNode(false)); 420 return importNode.firstChild; 421 }; 422 }; 423 if(!Sarissa.getParseErrorText){ 424 /** 425 * <p>Returns a human readable description of the parsing error. Usefull 426 * for debugging. Tip: append the returned error string in a <pre> 427 * element if you want to render it.</p> 428 * <p>Many thanks to Christian Stocker for the initial patch.</p> 429 * @argument oDoc The target DOM document 430 * @returns The parsing error description of the target Document in 431 * human readable form (preformated text) 432 */ 433 Sarissa.getParseErrorText = function (oDoc){ 434 var parseErrorText = Sarissa.PARSED_OK; 435 if(oDoc.parseError != 0){ 436 /*moz*/ 437 if(oDoc.documentElement.tagName == "parsererror"){ 438 parseErrorText = oDoc.documentElement.firstChild.data; 439 parseErrorText += "\n" + oDoc.documentElement.firstChild.nextSibling.firstChild.data; 440 }/*konq*/ 441 else if(oDoc.documentElement.tagName == "html"){ 442 parseErrorText = Sarissa.getText(oDoc.documentElement.getElementsByTagName("h1")[0], false) + "\n"; 443 parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("body")[0], false) + "\n"; 444 parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("pre")[0], false); 445 }; 446 }; 447 return parseErrorText; 448 }; 449 }; 450 Sarissa.getText = function(oNode, deep){ 451 var s = ""; 452 var nodes = oNode.childNodes; 453 for(var i=0; i < nodes.length; i++){ 454 var node = nodes[i]; 455 if(node.nodeType == Node.TEXT_NODE){ 456 s += node.data; 457 }else if(deep == true 458 && (node.nodeType == Node.ELEMENT_NODE 459 || node.nodeType == Node.DOCUMENT_NODE 460 || node.nodeType == Node.DOCUMENT_FRAGMENT_NODE)){ 461 462 s += Sarissa.getText(node, true); 463 }; 464 }; 465 return s; 466 }; 467 if(window.XMLSerializer){ 468 /** 469 * <p>Factory method to obtain the serialization of a DOM Node</p> 470 * @returns the serialized Node as an XML string 471 */ 472 Sarissa.serialize = function(oDoc){ 473 return (new XMLSerializer()).serializeToString(oDoc); 474 }; 475 }else{ 476 if((Sarissa.getDomDocument("","foo", null)).xml){ 477 // see non-IE version 478 Sarissa.serialize = function(oDoc) { 479 // TODO: check for HTML document and return innerHTML instead 480 return oDoc.xml; 481 }; 482 /** 483 * Utility class to serialize DOM Node objects to XML strings 484 * @constructor 485 */ 486 XMLSerializer = function(){}; 487 /** 488 * Serialize the given DOM Node to an XML string 489 * @param oNode the DOM Node to serialize 490 */ 491 XMLSerializer.prototype.serializeToString = function(oNode) { 492 return oNode.xml; 493 }; 494 }; 495 }; 496 if(window.XSLTProcessor){ 497 Sarissa.IS_ENABLED_XSLTPROC = true; 498 }; 499 /** 500 * strips tags from a markup string 501 */ 502 Sarissa.stripTags = function (s) { 503 return s.replace(/<[^>]+>/g,""); 504 }; 505 /** 506 * <p>Deletes all child nodes of the given node</p> 507 * @argument oNode the Node to empty 508 */ 509 Sarissa.clearChildNodes = function(oNode) { 510 while(oNode.hasChildNodes()){ 511 oNode.removeChild(oNode.firstChild); 512 }; 513 }; 514 /** 515 * <p> Replaces the childNodes of the toDoc object with the childNodes of 516 * the fromDoc object</p> 517 * <p> <b>Note:</b> The second object's original content is deleted before the copy operation</p> 518 * @argument nodeFrom the Node to copy the childNodes from 519 * @argument nodeTo the Node to copy the childNodes to 520 */ 521 Sarissa.copyChildNodes = function(nodeFrom, nodeTo) { 522 Sarissa.clearChildNodes(nodeTo); 523 var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument; 524 var nodes = nodeFrom.childNodes; 525 if(typeof(ownerDoc.importNode) == "function"){ 526 for(var i=0;i < nodes.length;i++) { 527 nodeTo.appendChild(ownerDoc.importNode(nodes[i], true)); 528 }; 529 } 530 else{ 531 for(var i=0;i < nodes.length;i++) { 532 nodeTo.appendChild(nodes[i].cloneNode(true)); 533 }; 534 }; 535 }; 536 537 /** 538 * <p>Serialize any object to an XML string. All properties are serialized using the property name 539 * as the XML element name. Array elements are rendered as <code>array-item</code> elements, 540 * using their index/key as the value of the <code>key</code> attribute.</p> 541 * @argument anyObject the object to serialize 542 * @argument objectName a name for that object 543 * @return the XML serializationj of the given object as a string 544 */ 545 Sarissa.xmlize = function(anyObject, objectName, indentSpace){ 546 indentSpace = indentSpace?indentSpace:''; 547 var s = indentSpace + '<' + objectName + '>'; 548 var isLeaf = false; 549 if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String 550 || anyObject instanceof Boolean || anyObject instanceof Date){ 551 s += Sarissa.escape(""+anyObject); 552 isLeaf = true; 553 }else{ 554 s += "\n"; 555 var itemKey = ''; 556 var isArrayItem = anyObject instanceof Array; 557 for(var name in anyObject){ 558 s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + " "); 559 }; 560 s += indentSpace; 561 }; 562 return s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n"); 563 }; 564 565 /** 566 * Escape the given string chacters that correspond to the five predefined XML entities 567 * @param sXml the string to escape 568 */ 569 Sarissa.escape = function(sXml){ 570 return sXml.replace(/&/g, "&") 571 .replace(/</g, "<") 572 .replace(/>/g, ">") 573 .replace(/"/g, """) 574 .replace(/'/g, "'"); 575 }; 576 577 /** 578 * Unescape the given string. This turns the occurences of the predefined XML 579 * entities to become the characters they represent correspond to the five predefined XML entities 580 * @param sXml the string to unescape 581 */ 582 Sarissa.unescape = function(sXml){ 583 return sXml.replace(/'/g,"'") 584 .replace(/"/g,"\"") 585 .replace(/>/g,">") 586 .replace(/</g,"<") 587 .replace(/&/g,"&"); 588 }; 589 // EOF