3 * ====================================================================
5 * ====================================================================
6 * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs.
7 * The library supports Gecko based browsers like Mozilla and Firefox,
8 * Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera
10 * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net
11 * ====================================================================
13 * ====================================================================
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 or
16 * the GNU Lesser General Public License version 2.1 as published by
17 * the Free Software Foundation (your choice between the two).
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License or GNU Lesser General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * or GNU Lesser General Public License along with this program; if not,
26 * write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * or visit http://www.gnu.org
31 * <p>Sarissa is a utility class. Provides "static" methods for DOMDocument and
32 * XMLHTTP objects, DOM Node serializatrion to XML strings and other goodies.</p>
37 Sarissa
.PARSED_OK
= "Document contains no parsing errors";
39 * Tells you whether transformNode and transformNodeToObject are available. This functionality
40 * is contained in sarissa_ieemu_xslt.js and is deprecated. If you want to control XSLT transformations
41 * use the XSLTProcessor
45 Sarissa
.IS_ENABLED_TRANSFORM_NODE
= false;
47 * tells you whether XMLHttpRequest (or equivalent) is available
50 Sarissa
.IS_ENABLED_XMLHTTP
= false;
52 * tells you whether selectNodes/selectSingleNode is available
55 Sarissa
.IS_ENABLED_SELECT_NODES
= false;
56 var _sarissa_iNsCounter
= 0;
57 var _SARISSA_IEPREFIX4XSLPARAM
= "";
58 var _SARISSA_HAS_DOM_IMPLEMENTATION
= document
.implementation
&& true;
59 var _SARISSA_HAS_DOM_CREATE_DOCUMENT
= _SARISSA_HAS_DOM_IMPLEMENTATION
&& document
.implementation
.createDocument
;
60 var _SARISSA_HAS_DOM_FEATURE
= _SARISSA_HAS_DOM_IMPLEMENTATION
&& document
.implementation
.hasFeature
;
61 var _SARISSA_IS_MOZ
= _SARISSA_HAS_DOM_CREATE_DOCUMENT
&& _SARISSA_HAS_DOM_FEATURE
;
62 var _SARISSA_IS_SAFARI
= (navigator
.userAgent
&& navigator
.vendor
&& (navigator
.userAgent
.toLowerCase().indexOf("applewebkit") != -1 || navigator
.vendor
.indexOf("Apple") != -1));
63 var _SARISSA_IS_IE
= document
.all
&& window
.ActiveXObject
&& navigator
.userAgent
.toLowerCase().indexOf("msie") > -1 && navigator
.userAgent
.toLowerCase().indexOf("opera") == -1;
64 if(!window
.Node
|| !window
.Node
.ELEMENT_NODE
){
65 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};
70 // for XSLT parameter names, prefix needed by IE
71 _SARISSA_IEPREFIX4XSLPARAM
= "xsl:";
72 // used to store the most recent ProgID available out of the above
73 var _SARISSA_DOM_PROGID
= "";
74 var _SARISSA_XMLHTTP_PROGID
= "";
76 * Called when the Sarissa_xx.js file is parsed, to pick most recent
77 * ProgIDs for IE, then gets destroyed.
78 * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object
79 * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled
81 pickRecentProgID = function (idList
, enabledList
){
84 for(var i
=0; i
< idList
.length
&& !bFound
; i
++){
86 var oDoc
= new ActiveXObject(idList
[i
]);
89 for(var j
=0;j
<enabledList
.length
;j
++)
90 if(i
<= enabledList
[j
][1])
91 Sarissa
["IS_ENABLED_"+enabledList
[j
][0]] = true;
92 }catch (objException
){
93 // trap; try next progID
97 throw "Could not retreive a valid progID of Class: " + idList
[idList
.length
-1]+". (original exception: "+e
+")";
101 // pick best available MSXML progIDs
102 _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]]);
103 _SARISSA_XMLHTTP_PROGID
= pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], [["XMLHTTP", 4]]);
104 _SARISSA_THREADEDDOM_PROGID
= pickRecentProgID(["Msxml2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
105 _SARISSA_XSLTEMPLATE_PROGID
= pickRecentProgID(["Msxml2.XSLTemplate.5.0", "Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"], [["XSLTPROC", 2]]);
106 // we dont need this anymore
107 pickRecentProgID
= null;
108 //============================================
109 // Factory methods (IE)
110 //============================================
111 // see non-IE version
112 Sarissa
.getDomDocument = function(sUri
, sName
){
113 var oDoc
= new ActiveXObject(_SARISSA_DOM_PROGID
);
114 // if a root tag name was provided, we need to load it in the DOM
117 // if needed, create an artifical namespace prefix the way Moz
120 oDoc
.loadXML("<a" + _sarissa_iNsCounter
+ ":" + sName
+ " xmlns:a" + _sarissa_iNsCounter
+ "=\"" + sUri
+ "\" />");
121 // don't use the same prefix again
122 ++_sarissa_iNsCounter
;
125 oDoc
.loadXML("<" + sName
+ "/>");
129 // see non-IE version
130 Sarissa
.getParseErrorText = function (oDoc
) {
131 var parseErrorText
= Sarissa
.PARSED_OK
;
132 if(oDoc
.parseError
!= 0){
133 parseErrorText
= "XML Parsing Error: " + oDoc
.parseError
.reason
+
134 "\nLocation: " + oDoc
.parseError
.url
+
135 "\nLine Number " + oDoc
.parseError
.line
+ ", Column " +
136 oDoc
.parseError
.linepos
+
137 ":\n" + oDoc
.parseError
.srcText
+
139 for(var i
= 0; i
< oDoc
.parseError
.linepos
;i
++){
140 parseErrorText
+= "-";
142 parseErrorText
+= "^\n";
144 return parseErrorText
;
146 // see non-IE version
147 Sarissa
.setXpathNamespaces = function(oDoc
, sNsSet
) {
148 oDoc
.setProperty("SelectionLanguage", "XPath");
149 oDoc
.setProperty("SelectionNamespaces", sNsSet
);
152 * Basic implementation of Mozilla's XSLTProcessor for IE.
153 * Reuses the same XSLT stylesheet for multiple transforms
156 XSLTProcessor = function(){
157 this.template
= new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID
);
158 this.processor
= null;
161 * Impoprts the given XSLT DOM and compiles it to a reusable transform
162 * @argument xslDoc The XSLT DOMDocument to import
164 XSLTProcessor
.prototype.importStylesheet = function(xslDoc
){
165 // convert stylesheet to free threaded
166 var converted
= new ActiveXObject(_SARISSA_THREADEDDOM_PROGID
);
167 converted
.loadXML(xslDoc
.xml
);
168 this.template
.stylesheet
= converted
;
169 this.processor
= this.template
.createProcessor();
170 // (re)set default param values
171 this.paramsSet
= new Array();
174 * Transform the given XML DOM
175 * @argument sourceDoc The XML DOMDocument to transform
176 * @return The transformation result as a DOM Document
178 XSLTProcessor
.prototype.transformToDocument = function(sourceDoc
){
179 this.processor
.input
= sourceDoc
;
180 var outDoc
= new ActiveXObject(_SARISSA_DOM_PROGID
);
181 this.processor
.output
= outDoc
;
182 this.processor
.transform();
186 * Set global XSLT parameter of the imported stylesheet
187 * @argument nsURI The parameter namespace URI
188 * @argument name The parameter base name
189 * @argument value The new parameter value
191 XSLTProcessor
.prototype.setParameter = function(nsURI
, name
, value
){
192 /* nsURI is optional but cannot be null */
194 this.processor
.addParameter(name
, value
, nsURI
);
196 this.processor
.addParameter(name
, value
);
198 /* update updated params for getParameter */
199 if(!this.paramsSet
[""+nsURI
]){
200 this.paramsSet
[""+nsURI
] = new Array();
202 this.paramsSet
[""+nsURI
][name
] = value
;
205 * Gets a parameter if previously set by setParameter. Returns null
207 * @argument name The parameter base name
208 * @argument value The new parameter value
209 * @return The parameter value if reviously set by setParameter, null otherwise
211 XSLTProcessor
.prototype.getParameter = function(nsURI
, name
){
213 if(nsURI
in this.paramsSet
&& name
in this.paramsSet
[nsURI
]){
214 return this.paramsSet
[nsURI
][name
];
220 else{ /* end IE initialization, try to deal with real browsers now ;-) */
221 if(_SARISSA_HAS_DOM_CREATE_DOCUMENT
){
223 * <p>Ensures the document was loaded correctly, otherwise sets the
224 * parseError to -1 to indicate something went wrong. Internal use</p>
227 Sarissa
.__handleLoad__ = function(oDoc
){
228 if (!oDoc
.documentElement
|| oDoc
.documentElement
.tagName
== "parsererror")
229 oDoc
.parseError
= -1;
230 Sarissa
.__setReadyState__(oDoc
, 4);
233 * <p>Attached by an event handler to the load event. Internal use.</p>
236 _sarissa_XMLDocument_onload = function(){
237 Sarissa
.__handleLoad__(this);
240 * <p>Sets the readyState property of the given DOM Document object.
243 * @argument oDoc the DOM Document object to fire the
244 * readystatechange event
245 * @argument iReadyState the number to change the readystate property to
247 Sarissa
.__setReadyState__ = function(oDoc
, iReadyState
){
248 oDoc
.readyState
= iReadyState
;
249 if (oDoc
.onreadystatechange
!= null && typeof oDoc
.onreadystatechange
== "function")
250 oDoc
.onreadystatechange();
252 Sarissa
.getDomDocument = function(sUri
, sName
){
253 var oDoc
= document
.implementation
.createDocument(sUri
?sUri
:"", sName
?sName
:"", null);
254 oDoc
.addEventListener("load", _sarissa_XMLDocument_onload
, false);
257 if(window
.XMLDocument
){
259 * <p>Emulate IE's onreadystatechange attribute</p>
261 XMLDocument
.prototype.onreadystatechange
= null;
263 * <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p>
264 * <ul><li>1 == LOADING,</li>
265 * <li>2 == LOADED,</li>
266 * <li>3 == INTERACTIVE,</li>
267 * <li>4 == COMPLETED</li></ul>
269 XMLDocument
.prototype.readyState
= 0;
271 * <p>Emulate IE's parseError attribute</p>
273 XMLDocument
.prototype.parseError
= 0;
275 // NOTE: setting async to false will only work with documents
276 // called over HTTP (meaning a server), not the local file system,
277 // unless you are using Moz 1.4+.
278 // BTW the try>catch block is for 1.4; I haven't found a way to check if
279 // the property is implemented without
280 // causing an error and I dont want to use user agent stuff for that...
281 var _SARISSA_SYNC_NON_IMPLEMENTED
= false;// ("async" in XMLDocument.prototype) ? false: true;
283 * <p>Keeps a handle to the original load() method. Internal use and only
284 * if Mozilla version is lower than 1.4</p>
287 XMLDocument
.prototype._sarissa_load
= XMLDocument
.prototype.load
;
290 * <p>Overrides the original load method to provide synchronous loading for
291 * Mozilla versions prior to 1.4, using an XMLHttpRequest object (if
292 * async is set to false)</p>
293 * @returns the DOM Object as it was before the load() call (may be empty)
295 XMLDocument
.prototype.load = function(sURI
) {
296 var oDoc
= document
.implementation
.createDocument("", "", null);
297 Sarissa
.copyChildNodes(this, oDoc
);
299 Sarissa
.__setReadyState__(this, 1);
301 if(this.async
== false && _SARISSA_SYNC_NON_IMPLEMENTED
) {
302 var tmp
= new XMLHttpRequest();
303 tmp
.open("GET", sURI
, false);
305 Sarissa
.__setReadyState__(this, 2);
306 Sarissa
.copyChildNodes(tmp
.responseXML
, this);
307 Sarissa
.__setReadyState__(this, 3);
310 this._sarissa_load(sURI
);
313 catch (objException
) {
314 this.parseError
= -1;
317 if(this.async
== false){
318 Sarissa
.__handleLoad__(this);
325 }//if(window.XMLDocument)
326 else if(document
.implementation
&& document
.implementation
.hasFeature
&& document
.implementation
.hasFeature('LS', '3.0')){
327 Document
.prototype.async
= true;
328 Document
.prototype.onreadystatechange
= null;
329 Document
.prototype.parseError
= 0;
330 Document
.prototype.load = function(sURI
) {
331 var parser
= document
.implementation
.createLSParser(this.async
? document
.implementation
.MODE_ASYNCHRONOUS
: document
.implementation
.MODE_SYNCHRONOUS
, null);
334 parser
.addEventListener("load",
337 Sarissa
.copyChildNodes(e
.newDocument
, self
.documentElement
, false);
338 self
.onreadystatechange
.call();
343 var oDoc
= parser
.parseURI(sURI
);
346 this.parseError
= -1;
349 Sarissa
.copyChildNodes(oDoc
, this.documentElement
, false);
353 * <p>Factory method to obtain a new DOM Document object</p>
354 * @argument sUri the namespace of the root node (if any)
355 * @argument sUri the local name of the root node (if any)
356 * @returns a new DOM Document
358 Sarissa
.getDomDocument = function(sUri
, sName
){
359 return document
.implementation
.createDocument(sUri
?sUri
:"", sName
?sName
:"", null);
362 };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT)
364 //==========================================
366 //==========================================
367 if(!window
.DOMParser
){
369 * DOMParser is a utility class, used to construct DOMDocuments from XML strings
372 DOMParser = function() {
374 if(_SARISSA_IS_SAFARI
){
376 * Construct a new DOM Document from the given XMLstring
377 * @param sXml the given XML string
378 * @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml).
379 * @return a new DOM Document from the given XML string
381 DOMParser
.prototype.parseFromString = function(sXml
, contentType
){
382 if(contentType
.toLowerCase() != "application/xml"){
383 throw "Cannot handle content type: \"" + contentType
+ "\"";
385 var xmlhttp
= new XMLHttpRequest();
386 xmlhttp
.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(str
), false);
388 return xmlhttp
.responseXML
;
390 }else if(Sarissa
.getDomDocument
&& Sarissa
.getDomDocument() && "loadXML" in Sarissa
.getDomDocument()){
391 DOMParser
.prototype.parseFromString = function(sXml
, contentType
){
392 var doc
= Sarissa
.getDomDocument();
399 if(window
.XMLHttpRequest
){
400 Sarissa
.IS_ENABLED_XMLHTTP
= true;
402 else if(_SARISSA_IS_IE
){
404 * Emulate XMLHttpRequest
407 XMLHttpRequest = function() {
408 return new ActiveXObject(_SARISSA_XMLHTTP_PROGID
);
410 Sarissa
.IS_ENABLED_XMLHTTP
= true;
413 if(!window
.document
.importNode
&& _SARISSA_IS_IE
){
416 * Implements importNode for the current window document in IE using innerHTML.
417 * Testing showed that DOM was multiple times slower than innerHTML for this,
418 * sorry folks. If you encounter trouble (who knows what IE does behind innerHTML)
419 * please gimme a call.
420 * @param oNode the Node to import
421 * @param bChildren whether to include the children of oNode
422 * @returns the imported node for further use
424 window
.document
.importNode = function(oNode
, bChildren
){
425 var importNode
= document
.createElement("div");
427 importNode
.innerHTML
= Sarissa
.serialize(oNode
);
429 importNode
.innerHTML
= Sarissa
.serialize(oNode
.cloneNode(false));
430 return importNode
.firstChild
;
434 if(!Sarissa
.getParseErrorText
){
436 * <p>Returns a human readable description of the parsing error. Usefull
437 * for debugging. Tip: append the returned error string in a <pre>
438 * element if you want to render it.</p>
439 * <p>Many thanks to Christian Stocker for the initial patch.</p>
440 * @argument oDoc The target DOM document
441 * @returns The parsing error description of the target Document in
442 * human readable form (preformated text)
444 Sarissa
.getParseErrorText = function (oDoc
){
445 var parseErrorText
= Sarissa
.PARSED_OK
;
446 if(oDoc
&& oDoc
.parseError
&& oDoc
.parseError
!= 0){
448 if(oDoc
.documentElement
.tagName
== "parsererror"){
449 parseErrorText
= oDoc
.documentElement
.firstChild
.data
;
450 parseErrorText
+= "\n" + oDoc
.documentElement
.firstChild
.nextSibling
.firstChild
.data
;
453 parseErrorText
= Sarissa
.getText(oDoc
.documentElement
);/*.getElementsByTagName("h1")[0], false) + "\n";
454 parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("body")[0], false) + "\n";
455 parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("pre")[0], false);*/
458 return parseErrorText
;
461 Sarissa
.getText = function(oNode
, deep
){
463 var nodes
= oNode
.childNodes
;
464 for(var i
=0; i
< nodes
.length
; i
++){
466 var nodeType
= node
.nodeType
;
467 if(nodeType
== Node
.TEXT_NODE
|| nodeType
== Node
.CDATA_SECTION_NODE
){
469 }else if(deep
== true
470 && (nodeType
== Node
.ELEMENT_NODE
471 || nodeType
== Node
.DOCUMENT_NODE
472 || nodeType
== Node
.DOCUMENT_FRAGMENT_NODE
)){
473 s
+= Sarissa
.getText(node
, true);
478 if(window
.XMLSerializer
){
480 * <p>Factory method to obtain the serialization of a DOM Node</p>
481 * @returns the serialized Node as an XML string
483 Sarissa
.serialize = function(oDoc
){
486 s
= oDoc
.innerHTML
?oDoc
.innerHTML
:(new XMLSerializer()).serializeToString(oDoc
);
491 if(Sarissa
.getDomDocument
&& (Sarissa
.getDomDocument("","foo", null)).xml
){
492 // see non-IE version
493 Sarissa
.serialize = function(oDoc
) {
496 s
= oDoc
.innerHTML
?oDoc
.innerHTML
:oDoc
.xml
;
501 * Utility class to serialize DOM Node objects to XML strings
504 XMLSerializer = function(){};
506 * Serialize the given DOM Node to an XML string
507 * @param oNode the DOM Node to serialize
509 XMLSerializer
.prototype.serializeToString = function(oNode
) {
516 * strips tags from a markup string
518 Sarissa
.stripTags = function (s
) {
519 return s
.replace(/<[^>]+>/g,"");
522 * <p>Deletes all child nodes of the given node</p>
523 * @argument oNode the Node to empty
525 Sarissa
.clearChildNodes = function(oNode
) {
526 // need to check for firstChild due to opera 8 bug with hasChildNodes
527 while(oNode
.firstChild
){
528 oNode
.removeChild(oNode
.firstChild
);
532 * <p> Copies the childNodes of nodeFrom to nodeTo</p>
533 * <p> <b>Note:</b> The second object's original content is deleted before
534 * the copy operation, unless you supply a true third parameter</p>
535 * @argument nodeFrom the Node to copy the childNodes from
536 * @argument nodeTo the Node to copy the childNodes to
537 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false
539 Sarissa
.copyChildNodes = function(nodeFrom
, nodeTo
, bPreserveExisting
) {
540 if((!nodeFrom
) || (!nodeTo
)){
541 throw "Both source and destination nodes must be provided";
543 if(!bPreserveExisting
){
544 Sarissa
.clearChildNodes(nodeTo
);
546 var ownerDoc
= nodeTo
.nodeType
== Node
.DOCUMENT_NODE
? nodeTo
: nodeTo
.ownerDocument
;
547 var nodes
= nodeFrom
.childNodes
;
548 if(ownerDoc
.importNode
&& (!_SARISSA_IS_IE
)) {
549 for(var i
=0;i
< nodes
.length
;i
++) {
550 nodeTo
.appendChild(ownerDoc
.importNode(nodes
[i
], true));
554 for(var i
=0;i
< nodes
.length
;i
++) {
555 nodeTo
.appendChild(nodes
[i
].cloneNode(true));
561 * <p> Moves the childNodes of nodeFrom to nodeTo</p>
562 * <p> <b>Note:</b> The second object's original content is deleted before
563 * the move operation, unless you supply a true third parameter</p>
564 * @argument nodeFrom the Node to copy the childNodes from
565 * @argument nodeTo the Node to copy the childNodes to
566 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is
568 Sarissa
.moveChildNodes = function(nodeFrom
, nodeTo
, bPreserveExisting
) {
569 if((!nodeFrom
) || (!nodeTo
)){
570 throw "Both source and destination nodes must be provided";
572 if(!bPreserveExisting
){
573 Sarissa
.clearChildNodes(nodeTo
);
575 var nodes
= nodeFrom
.childNodes
;
576 // if within the same doc, just move, else copy and delete
577 if(nodeFrom
.ownerDocument
== nodeTo
.ownerDocument
){
578 while(nodeFrom
.firstChild
){
579 nodeTo
.appendChild(nodeFrom
.firstChild
);
582 var ownerDoc
= nodeTo
.nodeType
== Node
.DOCUMENT_NODE
? nodeTo
: nodeTo
.ownerDocument
;
583 if(ownerDoc
.importNode
&& (!_SARISSA_IS_IE
)) {
584 for(var i
=0;i
< nodes
.length
;i
++) {
585 nodeTo
.appendChild(ownerDoc
.importNode(nodes
[i
], true));
588 for(var i
=0;i
< nodes
.length
;i
++) {
589 nodeTo
.appendChild(nodes
[i
].cloneNode(true));
592 Sarissa
.clearChildNodes(nodeFrom
);
597 * <p>Serialize any object to an XML string. All properties are serialized using the property name
598 * as the XML element name. Array elements are rendered as <code>array-item</code> elements,
599 * using their index/key as the value of the <code>key</code> attribute.</p>
600 * @argument anyObject the object to serialize
601 * @argument objectName a name for that object
602 * @return the XML serializationj of the given object as a string
604 Sarissa
.xmlize = function(anyObject
, objectName
, indentSpace
){
605 indentSpace
= indentSpace
?indentSpace
:'';
606 var s
= indentSpace
+ '<' + objectName
+ '>';
608 if(!(anyObject
instanceof Object
) || anyObject
instanceof Number
|| anyObject
instanceof String
609 || anyObject
instanceof Boolean
|| anyObject
instanceof Date
){
610 s
+= Sarissa
.escape(""+anyObject
);
615 var isArrayItem
= anyObject
instanceof Array
;
616 for(var name
in anyObject
){
617 s
+= Sarissa
.xmlize(anyObject
[name
], (isArrayItem
?"array-item key=\""+name
+"\"":name
), indentSpace
+ " ");
621 return s
+= (objectName
.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName
+ ">\n");
625 * Escape the given string chacters that correspond to the five predefined XML entities
626 * @param sXml the string to escape
628 Sarissa
.escape = function(sXml
){
629 return sXml
.replace(/&/g
, "&")
630 .replace(/</g
, "<")
631 .replace(/>/g
, ">")
632 .replace(/"/g, ""
;")
633 .replace(/'/g, "&apos
;");
637 * Unescape the given string. This turns the occurences of the predefined XML
638 * entities to become the characters they represent correspond to the five predefined XML entities
639 * @param sXml the string to unescape
641 Sarissa.unescape = function(sXml){
642 return sXml.replace(/'/g,"'")
643 .replace(/"/g,"\"")
644 .replace(/>/g,">")
645 .replace(/</g,"<")
646 .replace(/&/g,"&");