// 令Mozilla引擎的XPath兼容IE的代码
// mozXPath [http://km0ti0n.blunted.co.uk/mozxpath/] km0ti0n@gmail.com
// Code licensed under Creative Commons Attribution-ShareAlike License 
// http://creativecommons.org/licenses/by-sa/2.5/
if( document.implementation.hasFeature("XPath", "3.0") )
{
	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;
	}
	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;
		}
	}
	Element.prototype.selectNodes = function(cXPathString)
	{
		if(this.ownerDocument.selectNodes)
		{
			return this.ownerDocument.selectNodes(cXPathString, this);
		}
		else{throw "For XML Elements Only";}
	}
	Element.prototype.selectSingleNode = function(cXPathString)
	{	
		if(this.ownerDocument.selectSingleNode)
		{
			return this.ownerDocument.selectSingleNode(cXPathString, this);
		}
		else{throw "For XML Elements Only";}
	}
}

// 从string构建XML DOM对象
function parseXml(str) {
	var doc;
	if (window.DOMParser) { // Firefox
		var parser = new DOMParser();
		doc = parser.parseFromString(str, 'text/xml');
	} else { // IE
		doc = new ActiveXObject('Microsoft.XMLDOM');
		if (!doc.loadXML(str)) {
			alert(doc.parseError.srcText);
		}
	}

	return doc;
}

// 执行XSL转换
function xslTransform(xml, xslt) {
	if (window.XSLTProcessor) { // Firefox
		var processor = new XSLTProcessor();
		processor.importStylesheet(xslt);

		var result = processor.transformToDocument(xml);

		var xmls = new XMLSerializer();
		return xmls.serializeToString(result);
	} else { // IE
		return xml.transformNode(xslt);
	}
}

function xslTransformToFragment(xml, xslt, doc) {
	if (window.XSLTProcessor) { // Firefox
		var processor = new XSLTProcessor();
		processor.importStylesheet(xslt);

		return processor.transformToFragment(xml, doc);
	} else { // IE
		var result = xml.transformNode(xslt);
		var fragment = doc.createDocumentFragment();
		if (doc.body && doc.body.innerHTML) {
			var container = doc.createElement("div");
			container.innerHTML = result;
			while (container.hasChildNodes()) {
				fragment.appendChild(container.firstChild);
			}
		} else {
			var xdoc = createXml();
            if (result.substring(0, 5) == '<?xml') {
                result = result.substring(result.indexOf('?>') + 2);
            }
			xdoc.loadXML("<my>" + result + "</my>");
			var container = xdoc.documentElement;
			while (container.hasChildNodes()) {
				fragment.appendChild(container.firstChild);
			}
		}

		return fragment;
	}
}

function updateContentFromNode(xml, xslt, doc, node) {
	var fragment = xslTransformToFragment(xml, xslt, doc);
	clearChildNodes(node);
	node.appendChild(fragment);
}

// 按照XPath从XML结点取单个元素值
function xt(xml, path) {
	var node = xml.selectSingleNode(path);
	if (node == null) {
		return "";
	} else {
		return node.textContent || node.text;
	}
}

function createXml(node) {
	var xml;
    if(window.ActiveXObject) {
        xml = new ActiveXObject('Microsoft.XMLDOM');
        xml.async = false;
    } else if (document.implementation && document.implementation.createDocument) {
        xml = document.implementation.createDocument('', '', null);
    } else {
		return null;
    }
    if (node) xml.appendChild(node.cloneNode(true));
    return xml;
}

function clearChildNodes(node) {
	while (node.firstChild) {
		node.removeChild(node.firstChild);
	}
}
