/*
	NOTE: There is a bug in the getNode* methods where the RegExp used to locate
		the requested node will go into an infinite loop. This is caused by the
		inability of the RegExp to find nested tags with the same name.

		For example: searching through <foo><bar><foo>...</foo></bar></foo> for
			the "foo" node will return "<foo><bar><foo>...</foo>" rather than
			the string contianing the final "</foo>".

		It is unknown why this is an issue, however, it will cause the browser
		to lock up because the RegExp goes into an infinite loop.

	WORK-AROUND: Ensure the XML passed in DOES NOT contain nested tags of the
		same name, as in the example above.
*/

function getValue(xml, name)
{
	if (xml.length == 0)
		return null;

	var	_xml = null;

	if (typeof(name) != "undefined" && name.length != 0)
		_xml = getNode(xml, name);
	else
		_xml = xml;
//alert("_xml: " + _xml);
	if (_xml == null)
		return null;

	return _xml.replace(/<.*?>/g,"");
}

function getAttribute(xml, name, attribute)
{
	if (xml == null || xml.length == 0 || name == null || name.length == 0)
		return null;
/*
	// function can be called with 2 params, in which case "attribute" is
	// the second and the node is the target; switch "name" and "attribute"

	if (typeof(attribute) == "undefined")
	{
		attribute = name;
		name = null;
	}

	var	node, tag;

	if (name != null && name.indexOf(".") != -1)
	{
		var	path = name.substring(0, name.lastIndexOf("."));
		tag = path.substring(path.lastIndexOf(".") + 1).replace(/\[.*?\]/g,"");

		node = getNode(xml, path);
	}
	else
	{
		node = xml;

		tag = node.substring(1, node.indexOf(" "));
	}
*/
	if (typeof(attribute) == "undefined")
	{
		if (name.indexOf(".") != -1)
		{
			attribute = name.substring(name.lastIndexOf(".") + 1);
			name = name.substring(0, name.lastIndexOf("."));
		}
		else
		{
			attribute = name;
			name = null;
		}
	}

	var node, tag;

	if (name != null && name.indexOf(".") != -1)
	{
//	  var path = name.substring(0, name.lastIndexOf("."));

//	  if (name != null && attribute != null)
			path = name;

		tag = path.substring(path.lastIndexOf(".") + 1).replace(/\[.*?\]/g,"");
		node = getNode(xml, path);
	}
	else
	{
		node = xml;
		tag = node.substring(1, node.indexOf(" "));
	}
//alert(node);
	// only expect to find one, use "i"

	var	r = new RegExp("<" + tag + "(?: .*?=\".*?\")>", "i");

	var	tags = node.match(r);
//alert("tags: " + tags);
	if (tags == null)
		return null;

	// only expect to find one, use "i"

	r = new RegExp(" " + attribute + "=\"(.*?)\"", "i");

	var	attrs = tags[0].match(r);
//alert("attrs: " + attrs);
	if (attrs != null)
		return attrs[1];

	return null;
}

function getNodeByNum(xml, name, num)
{
//alert("--> " + xml);
	if (xml == null || xml.length == 0 || name == null || name.length == 0)
		return null;

	xml = xml.replace(/<!--.*?-->/g,"");

	if (xml.length == 0)
		return null;
//alert("looking for <" + name + ">...</" + name + ">");
//	var r = new RegExp("<" + name + "( .*?=\".*?\")*? */>", "gi");
	var r = new RegExp("<" + name + "((\\s+\\w+(\\s*=\\s*(?:[\"'].*?[\"']|[^'\">\\s]+))?)+\\s*|\\s*) *\/>", "gi");

	xml = xml.replace(r, "<" + name + "$1></" + name + ">");

	var i = 0;
	
	if ((i = xml.indexOf("<" + name)) == -1 ||
		xml.indexOf("</" + name + ">", i) == -1)
	{
		return null; 
	}

	// expect to find multiple, use "gi"

//	var	r = new RegExp("<" + name + "(?: .*?=\".*?\"|)+>(?:.*?[\\n\\r]*)+<\\/" + name + ">", "gi");
	var	r = new RegExp("<" + name + "((\\s+\\w+(\\s*=\\s*(?:[\"'].*?[\"']|[^'\">\\s]+))?)+\\s*|\\s*)>(?:[\\s\\S]*?)<\/" + name + ">", "gi")

	var	nodes = xml.match(r);
//alert("nodes (" + name + "/" + num + "): " + nodes + " " + (nodes != null ? nodes.length : 0));
	if (nodes == null)
		return null;

	return nodes[num];
}

function getNode(xml, name)
{
	var	parts = name.split(".");
	var	path = parts[0];

	var	_xml = xml;

	for (var i = 0; i < parts.length; i++)
	{
		var	num = 0;

		if (parts[i].charAt(parts[i].length - 1) == "]")
		{
			num = Number(parts[i].substring(parts[i].indexOf("[") + 1,
				parts[i].lastIndexOf("]")));

			parts[i] = parts[i].substring(0, parts[i].indexOf("["));
		}

		if ((_xml = getNodeByNum(_xml, parts[i], num)) == null)
			return null;
	}

	return _xml;
}

function loadXML(s)
{
	xml = new ActiveXObject("MSXML2.DOMDocument.4.0");

	xml.loadXML(s);

	return xml;
}

function xmlTree(xmlNode, level)
{
	if (typeof(level) == "undefined")
		level = 0;

	var	indent = "";

	for (i = 0; i < level; i++)
		indent += "&nbsp;&nbsp;"

	//by : micoxjcg@yahoo.com.br

	var treeTxt="";
	
	for (var i=0;i<xmlNode.childNodes.length;i++)
	{
		if(xmlNode.childNodes[i].nodeType == 1)
		{
			treeTxt += indent + "<nobr><font color=blue>&lt;</font>" +
				"<font color=brown>" + xmlNode.childNodes[i].nodeName +
				"</font>";

			var	node = xmlNode.childNodes[i];
			
			if(node.childNodes.length == 0)
			{
				for(var z=0;z<node.attributes.length;z++)
				{
					var atrib = node.attributes[z];
					
					treeTxt += " <font color=brown>" + atrib.nodeName +
						"</font>=\"<b>" + atrib.nodeValue + "</b>\"";
				}
				
				if (node.nodeValue == null)
					treeTxt += " <font color=blue>/&gt;</font>";
				else
					treeTxt += "<font color=blue>&gt;</font>" + node.nodeValue;

				treeTxt += "<br>\n";
			}
			else if(node.childNodes.length>0)
			{
				for(var z=0;z<node.attributes.length;z++)
				{
					var atrib = node.attributes[z];
					
					treeTxt += " <font color=brown>" + atrib.nodeName +
						"</font>=\"<b>" + atrib.nodeValue + "</b>\"";
				}

				if (node.firstChild.nodeValue == null)
				{
					treeTxt += "<font color=blue>&gt;</font>";
					treeTxt += "<br>\n" + xmlTree(node, level + 1);
					treeTxt += indent;
				}
				else
					treeTxt += "&gt;<b>" + node.firstChild.nodeValue + "</b>";

				treeTxt += "<font color=blue>&lt;/</font><font color=brown>" +
					node.nodeName + "</font><font color=blue>&gt;</font><br>";
			}

			treeTxt += "</nobr>";
		}
	}
	
	return treeTxt;
}
