
function XpathEvaluatorLight(xmlElement)
{
	this.oXmlElement = xmlElement;	
	
   this.getNodeStaff = function(nodeExpr) {
		var nodeName = "";
		var nodeAttrExpr = "";
		var nodeAttrName = "";
		var nodeAttrValue = "";  
		var nodeStaffArray = new Array();
		//[0] - nodeName
		//[1] - nodeAttrName
		//[2] - nodeAttrValue	

		//return cases:
		//nodeName exists, nodeAttrName and nodeAttrValue don't exist [1,0,0] - node without atttributes
		//nodeName, nodeAttrName and nodeAttrValue exist [1,1,1] - node with condition	
		//nodeName doesn't exist, nodeAttrName exists and nodeAttrValue doesn't exist - just attribute													

		var startIndex = 0;
		var endIndex = 0;
		
		if(nodeExpr.indexOf("@") == 0 && nodeExpr.indexOf("[") == -1)
		{
			nodeName = "";
			nodeAttrName = nodeExpr.substring(1,nodeExpr.length);
			nodeAttrValue = "";
		}
		else
		{
			endIndex = nodeExpr.indexOf("[");
			if(endIndex==-1)
				endIndex = nodeExpr.length; 
			nodeName = nodeExpr.substring(startIndex,endIndex);
		}
		
		if(nodeExpr.indexOf("[") != -1)
		{						
			startIndex = nodeExpr.indexOf("[");
			endIndex = nodeExpr.indexOf("]")+1;							
			nodeAttrExpr = nodeExpr.substring(startIndex,endIndex);

			if(nodeAttrExpr.indexOf("@")!=-1)
			{
				startIndex = nodeAttrExpr.indexOf("@")+1;
				if(nodeAttrExpr.indexOf("=")!=-1)
					endIndex = nodeAttrExpr.indexOf("=");	
				else if(nodeAttrExpr.indexOf(">")!=-1)
					endIndex = nodeAttrExpr.indexOf(">");	
				else if(nodeAttrExpr.indexOf("<")!=-1)
					endIndex = nodeAttrExpr.indexOf("<");		
				else
					endIndex = nodeAttrExpr.indexOf("]");																	
			}
			else
				endIndex = nodeAttrExpr.indexOf("]");	
			
			nodeAttrName = nodeAttrExpr.substring(startIndex,endIndex);

			if(nodeAttrExpr.indexOf("'")<nodeAttrExpr.lastIndexOf("'"))
			{
				startIndex = nodeAttrExpr.indexOf("'")+1;
				endIndex = nodeAttrExpr.lastIndexOf("'");
			}
			else if(nodeAttrExpr.indexOf("'")==-1 && endIndex!=(nodeAttrExpr.length-2))
			{
				// endIndex is index of "=", ">" or "<" 
				startIndex = endIndex+1;
				endIndex = nodeAttrExpr.length-1;
			}	
			else if(nodeAttrExpr.indexOf("'")!=-1 && nodeAttrExpr.indexOf("'")==nodeAttrExpr.lastIndexOf("'"))
				throw new Error("Wrong number of ' in XPath expression.");				
					
			if(startIndex<endIndex)
				nodeAttrValue = nodeAttrExpr.substring(startIndex,endIndex);	
			else if(startIndex==endIndex)	
				nodeAttrValue = "";
		}	
		
		nodeStaffArray.push(nodeName);
		nodeStaffArray.push(nodeAttrName);
		nodeStaffArray.push(nodeAttrValue);

		return nodeStaffArray;                
    };
    
    this.evaluateXpath = function(currXpath, rootNodeList, returnType) {  
    
		var nextChildNode;
		var nextChildNodeList; 
		var nextRootNodeList;
		var xPathArray;
		var nextXpath;
		var nodeStaffArray;
		var xPathCount;
		
		nextRootNodeList = new Array();
		xPathArray = currXpath.split("/");
		nodeStaffArray = this.getNodeStaff(xPathArray[0]);
		
		xPathArray.shift();
		xPathCount = xPathArray.length;
		nextXpath = xPathArray.join("/");
						
		for(i=0;i<rootNodeList.length;i++)	{
	
			if(nodeStaffArray[0]!="")
			{
				nextChildNodeList = rootNodeList[i].getElementsByTagName(nodeStaffArray[0]);
				for(j=0;j<nextChildNodeList.length;j++)
				{
					nextChildNode = nextChildNodeList[j];
					//nodeName exists, nodeAttrName and nodeAttrValue don't exist [1,0,0] - node without atttributes
					if(nodeStaffArray[0]!="" && nodeStaffArray[1]=="" && nodeStaffArray[2]=="")
					{
						nextRootNodeList.push(nextChildNode);							
					}
					//nodeName, nodeAttrName and nodeAttrValue exist [1,1,1] - node with condition	
					else if(nodeStaffArray[0]!="" && nodeStaffArray[1]!="" && nodeStaffArray[2]!="")	
					{
						if(nextChildNode.getAttribute(nodeStaffArray[1])==nodeStaffArray[2])	
							nextRootNodeList.push(nextChildNode);																		
					}

				}			
			}	
			//nodeName doesn't exist, nodeAttrName exists and nodeAttrValue doesn't exist [0,1,0] - just attribute													
			else if(nodeStaffArray[0]=="" && nodeStaffArray[1]!="" && nodeStaffArray[2]=="")
			{
				nextChildNode = rootNodeList[i];

				if(nextChildNode.getAttribute(nodeStaffArray[1])!=null && returnType=="var")	
					nextRootNodeList.push(nextChildNode.getAttribute(nodeStaffArray[1]));
				else
					throw new Error("Wrong returning type for this Xpath expression.");
			}										
		}

		if(xPathCount==0)
			return nextRootNodeList;
		else
			return this.evaluateXpath(nextXpath, nextRootNodeList, returnType);
		
		return;
    };              
        
    this.selectNodes = function(sXPath) {
		try
		{   
			if(sXPath.indexOf("//")==0)
				sXPath = sXPath.substring(2,sXPath.length);
			sXPath = sXPath.replace(/\s/g, "");
			//alert(sXPath);
			var returnType;
			var xPathArray = sXPath.split("/");
			var elementsArray = new Array();
			if(xPathArray[xPathArray.length-1].indexOf("@") == 0)
				returnType = "var";
			else
				returnType = "node";	

			elementsArray.push(this.oXmlElement);
			return this.evaluateXpath(sXPath, elementsArray, returnType);
		}
		catch (oError)
		{
			alert("selectNodes error");                                  
		}
		return;
	};   
	
    this.selectSingleNode = function(sXPath) {
		try
		{ 
			if(sXPath.indexOf("//")==0)
				sXPath = sXPath.substring(2,sXPath.length);
			sXPath = sXPath.replace(/\s/g, "");
			//alert(sXPath);		   
			var elementsArray = this.selectNodes(sXPath);
			if(elementsArray != null && elementsArray.length > 0)
				return elementsArray[0];
			else
				return null;
		}
		catch (oError)
		{
			alert("selectSingleNode error");                                  
		}
		return;
	};

    return this;
} 

 			
// handle onreadystatechange event of req object
function checkReadyState(xmlDom) {
	// only if oXmlDom shows "loaded"
	if (xmlDom.readyState == 4) 
	{
		// only if "OK"
		if (xmlDom.status == 200) 
	            return true;
		else
			alert("There was a problem retrieving the XML data:\n" + oXmlDom.statusText);
	}
	return false;
}
  
function initXmlDoc (xmlFilePath)	{ 
	try	{
		var oXmlDom = new XMLHttpRequest();
		oXmlDom.onreadystatechange = function(){checkReadyState(oXmlDom);};
		//false - wait until XML document will be downloaded (true - process script asynchronly
		oXmlDom.open("GET", xmlFilePath, false);
		oXmlDom.send(null);

		while(!checkReadyState(oXmlDom))
			setTimeout("checkReadyState(oXmlDom)",100);

		return oXmlDom.responseXML.documentElement;
	}
	catch (oError)
	{
		alert("initXmlDoc error");                                  
	}
	return;
}  
 							             
                

