function XmlDoc(async) {
   try {
      // W3c
      if (document.implementation && document.implementation.createDocument) {
         this.doc = document.implementation.createDocument("", "", null);
         // add custom support for readyState property
         if (this.doc.readyState == null) {
            this.doc.readyState = 1;
            this.doc.addEventListener("load", function () {
               this.doc.readyState = 4;
               if (typeof this.doc.onreadystatechange == "function")
                  this.doc.onreadystatechange();
            }, false);
         }
         //return doc;
      }
	  //win
      if (window.ActiveXObject){
		  this.doc = new ActiveXObject(getActiveXPrefix() + ".XmlDom");
         //return new ActiveXObject(getActiveXPrefix() + ".XmlDom");
	  }
	  //return this.doc;
	   this.doc.async = (async==null)?false:async;
   }catch (ex) {throw new Error("No Xml support");}
}

function XmlHttp() {	
	try {
      if (window.XMLHttpRequest){
         this.req = new XMLHttpRequest();         
         // add custom support for readyState property
		 /*does work in safari
         if (this.req.readyState == null) {
            this.req.readyState = 1;
            this.req.addEventListener("load", function () {
               this.req.readyState = 4;
               if (typeof this.req.onreadystatechange == "function")
                  this.req.onreadystatechange();
            }, false);
         }
		 */
         //return req;
      }
      if (window.ActiveXObject) {
        this.req = new ActiveXObject(getActiveXPrefix() + ".XmlHttp");
      }
   }catch (ex) {throw new Error("No XmlHttp support");}
}

function transformXmlFile(sXslFile, sXmlFile, oContainer){
	var oXSL = new XmlDoc();
	oXSL.loadDoc(sXslFile);

	var oXML = new XmlDoc();
	oXML.loadDoc(sXmlFile);

	if(window.XSLTProcessor){
		var xsltProcessor = new XSLTProcessor();		
		xsltProcessor.importStylesheet(oXSL.doc);	
		var fragment = xsltProcessor.transformToFragment(oXML.doc, document);
		oContainer.appendChild(fragment);
	}else{
		oContainer.innerHTML = oXML.doc.transformNode(oXSL.doc);
	}
}

function transformXmlObjs(oXSL, oXML, oContainer){
	if(window.XSLTProcessor){
		var xsltProcessor = new XSLTProcessor();		
		xsltProcessor.importStylesheet(oXSL.doc);	
		var fragment = xsltProcessor.transformToFragment(oXML.doc, document);
		oContainer.appendChild(fragment);
	}else{		
		oContainer.innerHTML = oXML.doc.transformNode(oXSL.doc);
	}
}

XmlDoc.prototype.testIt = function(){
	alert("testing");
}

XmlDoc.prototype.loadDoc = function(sFile){
	// branch for IE/Windows ActiveX version
	if (window.ActiveXObject){
		this.doc.load(sFile);
   // branch for Mozilla
	}else{
		var oXMLHTTP = new XMLHttpRequest();
		oXMLHTTP.open("GET",sFile, false);
		oXMLHTTP.overrideMimeType('text/xml');
		oXMLHTTP.send(null);
		this.copyDOM(oXMLHTTP.responseXML);
	}
	return this.doc;
}

XmlDoc.prototype.loadXML = function(strXML){
	// branch for IE/Windows ActiveX version
	if (window.ActiveXObject) {
		this.doc.loadXML(strXML);
	// branch for Mozilla
	}else{
		var oDoc = (new DOMParser()).parseFromString(strXML, "text/xml");
		this.copyDOM(oDoc);
	}
	return this.doc;
}

XmlHttp.prototype.getDoc = function(){
	var oDoc = new XmlDoc();
	// branch for IE/Windows ActiveX version
	if (window.ActiveXObject) {
		oDoc.loadXML(this.req.responseXML.xml);
	// branch for Mozilla
	}else{
		oDoc.copyDOM(this.req.responseXML);
	}
	return oDoc;
}

XmlDoc.prototype.selectNodes = function(sExpr, contextNode){
	//IE
	if (window.ActiveXObject){
		return this.doc.selectNodes(sExpr);
   //Mozilla
	}else{
		var ctx = contextNode?contextNode:this.doc;
		var nsresolver = (this.doc.documentElement) ? this.doc.createNSResolver(this.doc.documentElement) : null;
		var oResult = this.doc.evaluate(sExpr,ctx, nsresolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);	
		//var oResult = this.doc.evaluate(sExpr,ctx, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);	
		var nodeList = new Array(oResult.snapshotLength);
		for(var i=0;i<nodeList.length;i++){
			nodeList[i] = oResult.snapshotItem(i);
		}
		return nodeList;
	}
}

XmlDoc.prototype.selectSingleNode = function(sExpr, contextNode){
	//IE
	if (window.ActiveXObject){
		return this.doc.selectSingleNode(sExpr);
   //Mozilla
	}else{
		var ctx = contextNode?contextNode:null;
		sExpr += "[1]";
		var nodeList = this.selectNodes(sExpr, ctx);
		if(nodeList.length > 0){
			return nodeList[0];
		}else{
			return null;
		}
	}
}

XmlDoc.prototype.copyDOM = function(oDoc){
	this.clearDOM();
	if(oDoc.nodeType == Node.DOCUMENT_NODE || oDoc.nodeType == Node.DOCUMENT_FRAGMENT_NODE)
	{
		var oNodes = oDoc.childNodes;
		for(var i=0;i<oNodes.length;i++)
			this.doc.appendChild(this.doc.importNode(oNodes[i], true));
	}
	else if(oDoc.nodeType == Node.ELEMENT_NODE)
		this.doc.appendChild(this.doc.importNode(oDoc, true));
}

XmlDoc.prototype.clearDOM = function(){
	while(this.doc.hasChildNodes()){
		this.doc.removeChild(this.doc.firstChild);
	}
}

if (document.implementation && document.implementation.createDocument) {
	Node.prototype.__defineGetter__("xml", _Node_getXML);
 }
function _Node_getXML() {
    var oXMLSerializer = new XMLSerializer;
    var sXML = oXMLSerializer.serializeToString(this);
    return sXML;
}

function getActiveXPrefix() {
   if (getActiveXPrefix.prefix)
      return getActiveXPrefix.prefix;   
   var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
   var o, o2;
   for (var i = 0; i < prefixes.length; i++) {
      try {
         // try to create the objects
         o = new ActiveXObject(prefixes[i] + ".XmlHttp");
         o2 = new ActiveXObject(prefixes[i] + ".XmlDom");
         return getActiveXPrefix.prefix = prefixes[i];
      }
      catch (ex) {};
   }
   throw new Error("Could not find an installed XML parser");
}

function showXml(xmlObj){
	if(window.clipboardData){
		window.clipboardData.setData("Text",xmlObj.xml);
	}
	alert(xmlObj.xml);
}