﻿//@@@ Cross browser XML impementation
//@@@ Author: Gleyser Denis
//@@@ Tested with IE6.0, Mozilla 2.0, Opera 9.02
/*@@@ public functions interface 
   xml_CreateDOMFromPath(url) : creates xml dom object and loads remote data
   xml_CreateDOMFromXMLString(xmlString) : creates xml dom object and loads xml string (assync = false) 
   xml_GetDOMFromXMLIsland(XmlIslandId) : gets xml dom object from xml island                             
@@@ ------------------------------------------------------------ @@@*/
      
var xml_Ver = "";
try{
    if(window.ActiveXObject) xml_Ver = "IE";
else if(document.implementation && document.implementation.createDocument) 
    xml_Ver = "MZ";
    else xml_Ver = "";
}catch(e){
    if(document.implementation && document.implementation.createDocument) 
    xml_Ver = "MZ";
    else xml_Ver = "";
}

//@@@ iplementation missinj methods and properties for mozilla
if(xml_Ver=="MZ"){ //@@@ if( document.implementation.hasFeature("XPath", "3.0") )
    //@@@ prototying the XMLDocument.loadXML()
    XMLDocument.prototype.loadXML = function(strXML) {        
       var objDOMParser = new DOMParser();
       var objDoc = objDOMParser.parseFromString(strXML, "text/xml");
       while(this.hasChildNodes())this.removeChild(this.lastChild); 
       for (var i=0; i < objDoc.childNodes.length; i++) {            
          var objImportedNode = this.importNode(objDoc.childNodes[i], true);            
          this.appendChild(objImportedNode);        
       }
    }

    //@@@ prototying the Node.xml property
    function xml_Node_getXML() {    
        var objXMLSerializer = new XMLSerializer;
        var strXML = objXMLSerializer.serializeToString(this);
        return strXML;
    }
    Node.prototype.__defineGetter__("xml", xml_Node_getXML);            


    //@@@ prototying the XMLDocument.selectNodes()
    XMLDocument.prototype.selectNodes = function(cXPathString, xNode){
       if(!xNode){xNode = this;} 
       var oNSResolver = this.createNSResolver(this.documentElement);
       var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
       var aResult = [];
       for( var i = 0; i < aItems.snapshotLength; i++){
          aResult[i] =  aItems.snapshotItem(i);
       }
       return aResult;
    }

    //@@@ prototying the Element.selectNodes()
    Element.prototype.selectNodes = function(cXPathString){
        if(this.ownerDocument.selectNodes){
           return this.ownerDocument.selectNodes(cXPathString, this);
        }else{
           throw "For XML Elements Only";
        }
    }

    //@@@ prototying the XMLDocument.selectSingleNode()
    XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode){
        if(!xNode) {xNode = this;} 
        var xItems = this.selectNodes(cXPathString, xNode);
        if(xItems.length > 0){
            return xItems[0];
        }else{
            return null;
        }
    }

    //@@@ prototying the Element.selectSingleNode()
    Element.prototype.selectSingleNode = function(cXPathString){    
        if(this.ownerDocument.selectSingleNode){
            return this.ownerDocument.selectSingleNode(cXPathString, this);
        }else{
            throw "For XML Elements Only";
        }	        
    }
    
           
    //@@@ prototying the XMLDocument.transformNodeToObject()
    XMLDocument.prototype.transformNodeToObject = function(xslDoc, oResult){
		var xsltProcessor = new XSLTProcessor();
		if(xsltProcessor.reset){
            //@@@ new nsIXSLTProcessor is available
            xsltProcessor.importStylesheet(xslDoc);
            var newFragment = xsltProcessor.transformToFragment(this, oResult);
            oResult.__copyDOM(newFragment);
	    }else{
            //@@@ only nsIXSLTProcessorObsolete is available
            xsltProcessor.transformDocument(this, xslDoc, oResult, null);
        }		
	}
    
    
    //@@@ prototying the XMLDocument.transformNode()
    XMLDocument.prototype.transformNode = function(xslDoc){
		var out = document.implementation.createDocument("", "", null);
		this.transformNodeToObject(xslDoc, out);
		var serializer = new XMLSerializer();
		var str = serializer.serializeToString(out);		
		return str;					
	}
	
    
    //@@@ prototying the Element.transformNodeToObject()
    Element.prototype.transformNodeToObject = function(xslDoc, oResult){
		var oDoc = document.implementation.createDocument("", "", null);
		oDoc.__copyDOM(this);
		oDoc.transformNodeToObject(xslDoc, oResult);
	}
	
    
    //@@@ prototying the Element.transformNode()
    Element.prototype.transformNode = function(xslDoc){
        var oDoc = document.implementation.createDocument("", "", null);
		oDoc.__copyDOM(this);
		return oDoc.transformNode(xslDoc);
	}
	
	
	XMLDocument.prototype.__copyDOM = function(oDoc){
		//@@@ clear doom
		while(this.hasChildNodes())this.removeChild(this.firstChild);
		//@@@ copy
		if(oDoc.nodeType == Node.DOCUMENT_NODE || oDoc.nodeType == Node.DOCUMENT_FRAGMENT_NODE){
            var oNodes = oDoc.childNodes;
            for(i=0;i<oNodes.length;i++)this.appendChild(this.importNode(oNodes[i], true));
        }else if(oDoc.nodeType == Node.ELEMENT_NODE)this.appendChild(this.importNode(oDoc, true));
	}
}//@@@ end of //@@@ iplementation missinj methods and properties for mozilla  
      

function xml_CreateDOMFromPath(url){
    if(xml_Ver=="IE"){
         var oXml = new ActiveXObject("MSXML2.DomDocument");
         oXml.async = false;
         if(url!=null && url!=""){
             oXml.load(url);
         }
         return oXml;
    }else if(xml_Ver=="MZ"){
         var oXml = document.implementation.createDocument("", "", null);
         oXml.async = false;
         if(url!=null && url!=""){
             oXml.load(url);
         }
         return oXml;                                                        
    }        
}

function xml_CreateDOMFromXMLString(xmlString){
    if(xml_Ver=="IE"){
         var oXml = new ActiveXObject("MSXML2.DomDocument");
         oXml.async = false;
         if(xmlString!=null && xmlString!=""){
             oXml.loadXML(xmlString);
         }
         return oXml;
    }else if(xml_Ver=="MZ"){
         if(xmlString==null || xmlString==""){
             var oXml = document.implementation.createDocument("", "", null);
             return oXml;
         }else{
             var objDOMParser = new DOMParser(); 
             var oXml = objDOMParser.parseFromString(xmlString, "text/xml");                     
             return oXml;
         }                                        
    }
}

function xml_GetDOMFromXMLIsland(XmlIslandId){
    var oIsland = document.getElementById(XmlIslandId);
    if(xml_Ver=="IE"){
         return oIsland.XMLDocument;                 
    }else if(xml_Ver=="MZ"){
         var oXMLSerializer = new XMLSerializer();
         var sXml = oXMLSerializer.serializeToString(oIsland.firstChild); //@@@ upper case for Element Names and Lover case for attributes names problem
         return xml_CreateDOMFromXMLString(sXml); 
    } 
}                                          



