/*
	newXMLDocument()

	W3C DOM's are extended with these methods/properties from the MSXML DOM:
		XMLDocument.loadXML(XMLText)
		XMLDocument.transformNode(XSLDOM) (Document only extended)	
		Element.selectSingleNode(Xpath)
		Element.selectNodes(XPath)
		Element.xml
		Node.text	
*/

function newXMLDocument() {
	if (document.implementation && document.implementation.createDocument) {
		return document.implementation.createDocument('', '', null);
	} else {
		/*@cc_on
			@if (@_jscript_version >= 5)
				try {
					return new ActiveXObject("MSXML2.DOMDocument.4.0");
				} catch (ex){
					try {
						return new ActiveXObject("MSXML2.DOMDocument");
					} catch (ex) {
						try {	
							return new ActiveXObject("Microsoft.XMLDOM");
						} catch (ex2){
						return false;
					}
				}
			}
			@end
		@*/
	}
	return false;
}

function insertAfter(newChild, refChild) {
	if (refChild.nextSibling) {
		return refChild.parentNode.insertBefore(newChild, refChild.nextSibling);
	} else {
		return refChild.parentNode.appendChild(newChild);
	}
}

function NSResolver(prefix) {
	switch (prefix) {
		case 'SOAP-ENV' : return 'http://schemas.xmlsoap.org/soap/envelope/';
	}
	return null;
}

if (typeof(XMLDocument) != 'undefined') {
	XMLDocument.prototype.loadXML = function (text) {
		var xml = (new DOMParser()).parseFromString(text, "text/xml");
		while (this.hasChildNodes()) {
			this.removeChild(this.lastChild);
		}
		for (var i = 0; i < xml.childNodes.length; i++) {
			this.appendChild(this.importNode(xml.childNodes[i], true));
		}
	};
		
	XMLDocument.prototype.transformNode = function(stylesheet) {
		var result = document.implementation.createDocument('', '', null);
		try {
			new XSLTProcessor().transformDocument(this, stylesheet, result, null);
		} catch(ex) {
			return false;
		}
		try {
			return new XMLSerializer().serializeToString(result);
		} catch(ex) {
			return false;
		}
	}
		
	XMLDocument.prototype.selectNodes = Element.prototype.selectNodes = function(XPath, NSResolver) {
		var result = [];
		result.item = function(index){return result[index]}
		try {
			var doc = (this.implementation ? this : this.ownerDocument);
			var nodes = doc.evaluate(XPath, this, NSResolver, 5, null);
			var node = nodes.iterateNext();
			while(node) {
				result[result.length] = node;
				node = nodes.iterateNext();
			}
		} catch(ex) {
			return false;
		}
		return result;
	}
	
	XMLDocument.prototype.selectSingleNode = Element.prototype.selectSingleNode = function(XPath, NSResolver) {
		try {
			var result = (this.implementation ? this : this.ownerDocument);
			return result.evaluate(XPath, this, NSResolver, 9, null).singleNodeValue;
		} catch(ex) {
			return false;
		}
	}
	
	XMLDocument.prototype.__defineGetter__("xml", function (){
		try {
			return (new XMLSerializer()).serializeToString(this);
		} catch(ex) {
			return false;
		}
	});
	
	Element.prototype.__defineGetter__("xml", function (){
		try {
			return (new XMLSerializer()).serializeToString(this);
		} catch(ex) {
			return false;
		}
	});
	
	Node.prototype.__defineGetter__("text", function()
	{
		try {
			var result = '';
			if(this.nodeType==3) {return this.nodeValue}
			if(this.hasChildNodes()) {
				var children = this.childNodes;
				for(var i=0;i<children.length;i++) {
					var n = children[i];
					if(n.nodeType == 1 && n.hasChildNodes()) {result += n.text}
					if(n.nodeType == 3 || n.nodeType == 4) {result += n.nodeValue}
				}
			}
			return result;
		} catch(ex) {
			return false;
		}
	});					
}
