// Copyright 2007 julius2600
// All Rights Reserved
//
// xmlproc.js 0.3 try
//Author: julius2600 <snownetwork@gmail.com>
//QQ:7477247

// XMLProcessor
//
//创建对象
//xmlproc = new getXMLProcessor();
//返回xmlproc，如果失败返回false，所有操作都将返回false。

//xmldoc = xmlproc.createdoc(url);  
//得到一个相对标准的XMLDocument，由于黑心企业竞争关系，只是相对标准，并不支持所有的W3C XMLDocument操作。建议用XMLProcessor操作它。
//给出url会以load办法从url加载xml进来，否则产生干净的XMLDocument。如果load错误会产生带有load错误空白XMLDocument。
//load超时随浏览器而异

//xmldoc = xmldoc.send(url,data);
//用xmlhttp异步方式往外发送xml数据，url是发送的地址，data可以是由createdoc创建的一个相对标准的XMLDocument，也可以是字符型的xml序列
//操作返回从服务器得来的XMLDocument。这个XMLDocument由xmlhttp衍生，比起createdoc创建的更不标准，但是支持send操作。不过还建议用XMLProcessor操作它。
//改函数没有错误控制

//xmls = xmldoc.serialize(xmldoc);
//把一个XMLDocument变成xml序列，就是把对象序列化。xmldoc可以是相对标准的XMLDocument;
//返回字符型的xml序列
//改函数没有错误控制

//element = xsltprocessor(xmldoc,xsldoc);
//根据xsldoc的格式，进行xmldoc的格式化。xsldoc和xmldoc可以是相对标准的XMLDocument;
//返回一个element，可以进行append到页面。
//改函数没有错误控制

//element = xmldoc.selectnode(xmldoc,path)
//查找或遍历获得XMLDocument中的一个element，xmldoc可以是相对标准的XMLDocument，path是路径，如果第二次调用相同的路径，获得下一个节点。
//返回一个element，不可以进行append到页面。
//改函数没有错误控制

//element = createelement(tagname);
//创建一个element，tagname是该element的名字，不为空，不能是空间域
//返回一个element，不可以进行append到页面。
//改函数没有错误控制

//text = getelement(element)
//得到element的值，element就是一个element。
//返回字符型text。
//改函数没有错误控制

//element = setelement(element,text)
//设置element的值，element就是一个element，text要设置的值字符型
//返回element。
//改函数没有错误控制

//text = getattribute(element,attribute)
//得到element属性的值，element就是一个element。attribute是属性名称。
//返回字符型text。
//改函数没有错误控制

//element = setattribute(element,attribute.text)
//设置element的属性值，element就是一个element，attribute是属性名称，text要设置的值字符型
//返回element。
//改函数没有错误控制


//
function getXMLProcessor()
{
	//全局变量空间
	this.browser = false;  //浏览器类型，Mozilla or Internet Explorer
	this.parser = false;   //DOMParser() object
	this.xslt = false;     //XSLTProcessor()  object
	this.xmls = false;     //XMLSerializer() object
	this.xpath = false;    //XPathEvaluator() object
	this.xmldoc = false;   //XMLDocument() object
	this.xmlhttp = false;  //XMLHttpRequest() object
	this.xpathresults = false;  //Evaluator 操作的结果集 
	this.xpathresult = false;   //Evaluator 操作的结果
	this.xpathpath = false;     //xpath的path，遍历时用。这把这个值清空可以重新遍历
	
	getXMLProcessor.init.call(this);
}

getXMLProcessor.initXMLDocument = function ()
{
	var xmldoc = false;
	try
	{
		if(typeof document.implementation!='undefined' && typeof document.implementation.createDocument!='undefined')
		{
			xmldoc = document.implementation.createDocument('', '', null);
		}
		else if(window.ActiveXObject)
		{
			try
			{
				xmldoc = new ActiveXObject('Msxml2.XMLDOM');
			}
			catch (e)
			{
				xmldoc = new ActiveXObject('Microsoft.XMLDOM');
			}
		}
		else
		{
			xmldoc = false;
		}
	}
	catch (E)
	{
		xmldoc = false;
	}
	if(xmldoc)
	{
		xmldoc.async = false;
		xmldoc.appendChild(xmldoc.createProcessingInstruction('xml','version="1.0" encoding="UTF-8"'));
	}
	return xmldoc;
}

getXMLProcessor.init = function ()
{
	try
	{
		if(typeof XSLTProcessor!='undefined' && typeof XMLSerializer!='undefined' && typeof XPathEvaluator!='undefined' && typeof XMLHttpRequest!='undefined')
		{
			this.parser = new DOMParser(); 
			this.xslt = new XSLTProcessor();
			this.xmls = new XMLSerializer();
			this.xpath = new XPathEvaluator();
			this.xmlhttp = new XMLHttpRequest();
			this.xmldoc = getXMLProcessor.initXMLDocument.call();
			this.browser = 'MOZILLA';
		}
		else if(window.ActiveXObject)
		{
			this.xmldoc = getXMLProcessor.initXMLDocument.call();
			try
			{
				this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch(e)
			{
				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			this.browser = 'IE';
		}
	}
	catch(e)
	{
		this.browser = false;
	}
}


getXMLProcessor.prototype.xparse = function(string)
{
	if(this.browser == 'MOZILLA')
	{
		return this.parser.parseFromString(string, "text/xml");
	}
	else if(this.browser == 'IE')
	{
		var xmldoc = getXMLProcessor.initXMLDocument.call();
		xmldoc.async = false;
		xmldoc.loadXML(string);
		return xmldoc
	}
	else
	{
		return false;
	}	
}

getXMLProcessor.prototype.createdoc = function(url)
{
	var xmldoc = getXMLProcessor.initXMLDocument.call();
	if(xmldoc && url != null)
	{
		xmldoc.load(url);
	}
	return xmldoc;
}

getXMLProcessor.prototype.send = function(url,data)
{
	if(!this.xmlhttp || this.xmlhttp.readyState == 2 || this.xmlhttp.readyState == 3)
	{
		return false;
	}
	else
	{
		this.xmlhttp.abort();
		this.xmlhttp.open("POST",url, false);
		//this.xmlhttp.setRequestHeader('Content-Type','text/xml');
		this.xmlhttp.setRequestHeader('application','xmlproc/0.2');
		this.xmlhttp.send(data);
		return this.xmlhttp.responseXML;
	}
}

getXMLProcessor.prototype.serialize = function(xmldoc)
{
	if(this.browser == 'MOZILLA')
	{
		return this.xmls.serializeToString(xmldoc)
	}
	else if(this.browser == 'IE')
	{
		return xmldoc.xml;
	}
	else
	{
		return false;
	}
}

getXMLProcessor.prototype.xsltprocessor = function(xmldoc,xsldoc)
{
	var htmlelement; //only for IE
	if(this.browser == 'MOZILLA')
	{
		this.xslt.reset();
		this.xslt.importStylesheet(xsldoc);
		return this.xslt.transformToFragment(xmldoc,document);
	}
	else if(this.browser == 'IE')
	{
		htmlelement = document.createElement();
		htmlelement.innerHTML = xmldoc.transformNode(xsldoc);
		return htmlelement;
	}
	else
	{
		return false;
	}
}

getXMLProcessor.prototype.selectnode = function (xmldoc,path)
{
	if(this.browser == 'MOZILLA')
	{
		if(this.xpathpath != path)
		{
			this.xpathpath = path;
			this.xpathresults = this.xpath.evaluate(path,xmldoc,null,XPathResult.ANY_TYPE,null);
		}
		if(this.xpathresult = this.xpathresults.iterateNext())
		{
			return this.xpathresult;
		}
		else
		{
			return false;
		}
	}
	else if(this.browser == 'IE')
	{
		if(this.xpathpath != path)
		{
			this.xpathpath = path;
			this.xpathresults = xmldoc.selectNodes(path);
			this.xpathresult = 0
		}
		else
		{
			this.xpathresult++;
		}
		if(this.xpathresults.item(this.xpathresult))
		{
			return this.xpathresults.item(this.xpathresult);
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}

}

getXMLProcessor.prototype.createelement = function (tagname)
{
	if(this.browser == 'MOZILLA' || this.browser == 'IE')
	{
		return this.xmldoc.createElement(tagname);
	}
	else
	{
		return false;
	}
}

getXMLProcessor.prototype.getelement = function (element)
{
	if(this.browser == 'MOZILLA')
	{
		return element.textContent
	}
	else if(this.browser == 'IE')
	{
		return element.text
	}
	else
	{
		return false;
	}
}

getXMLProcessor.prototype.setelement = function (element,text)
{
	if(this.browser == 'MOZILLA')
	{
		element.textContent = text;
		return element;
	}
	else if(this.browser == 'IE')
	{
		element.text = text;
		return element;
	}
	else
	{
		return false;
	}
}

getXMLProcessor.prototype.getattribute = function (element,attribute)
{
	if(this.browser == 'MOZILLA' || this.browser == 'IE')
	{
		return element.getAttribute(attribute);
	}
	else
	{
		return false;
	}
}

getXMLProcessor.prototype.setattribute = function (element,attribute,value)
{
	if(this.browser == 'MOZILLA' || this.browser == 'IE')
	{
		return element.setAttribute(attribute,value);
	}
	else
	{
		return false;
	}
}


//快捷操作

getXMLProcessor.prototype.selectnv = function (xmldoc,path)
{
	var element;
	if(this.browser == 'MOZILLA')
	{
		if(element = this.selectnode(xmldoc,path))
		{
			return this.getelement(element);
		}
		else
		{
			return false;
		}
	}
	else if(this.browser == 'IE')
	{
		if(element = this.selectnode(xmldoc,path))
		{
			return this.getelement(element);
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

getXMLProcessor.prototype.selectna = function (xmldoc,path,attribute)
{
	var element;
	if(this.browser == 'MOZILLA' || this.browser == 'IE')
	{
		if(element = this.selectnode(xmldoc,path))
		{
			return this.getattribute(element,attribute);
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

