/******************************************************************************

	[clientlibrary] xml.js

	XML helper functions

	[author]		Ulf Johansen and others
	[version]		3.0
	[package]		core

******************************************************************************/


///////////////////////////////////////////////////////////////////////////////
//
//	Public functions
//
///////////////////////////////////////////////////////////////////////////////


/**********************************************************

	[function] ParseXML

	Parses the XML fragment and returns to document element

	[in]	strXML			The XML fragment
	[in]	bUseDefaultDTD	Use the default DTD for entity definitions

	[return]	The root node, or null in case of an error

***********************************************************/
function ParseXML( strXML, bUseDefaultDTD, bUseXPath )
{
	// Create XML DOM node
	var objDoc;
	try 
	{
		objDoc = new ActiveXObject( "Msxml2.DOMDocument" );
	}
	catch ( e )
	{
		alert( "INTERNAL ERROR: XML DOM 3.0 is not installed!" );
		return null;
	}

	objDoc.async			= false;
	objDoc.validateOnParse	= false;
	objDoc.resolveExternals = false;

	var strPrefix = 
		'<?xml version="1.0"?>\n' + 
		'<!DOCTYPE content [\n'+ 
			'<!ENTITY nbsp   "&#160;">\n' +
			'<!ENTITY AElig  "&#198;">\n' +
			'<!ENTITY Oslash "&#216;">\n' +
			'<!ENTITY Aring  "&#197;">\n' +
			'<!ENTITY aelig  "&#230;">\n' +
			'<!ENTITY oslash "&#248;">\n' +
			'<!ENTITY aring  "&#229;">\n' +
		"]>\n<content>";

	var strPostfix = "</content>";

	if ( bUseDefaultDTD )
	{
		strXML = strPrefix + strXML + strPostfix;
	}

	if ( bUseXPath )
	{
		// Use XPath instead of XSLPattern
		objDoc.setProperty( "SelectionLanguage", "XPath" );
	}

	if ( ! objDoc.loadXML( strXML ) )
	{
		var objError = objDoc.parseError;
		var strError = "ParseXML() in xml.js: Syntax error in XML-fragment in line: " + 
			objError.line + ", position " + objError.linepos + ".\n<br>\n" + 
			"Reason: " + objError.reason;

		var strErroneousLine = objError.srcText;
		var nOffsetChars = 10;
		strErroneousLine = strErroneousLine.substr(objError.linepos - nOffsetChars, 80);

		strError += '\nDetail of xml-fragment at erroneous character position minus ' + nOffsetChars + ' chars:\n';
		strError += strErroneousLine;
		strError += "\n\nSource xml:\n" + objError.srcText;

		alert( strError );
		return null;
	}

	return bUseDefaultDTD ? objDoc.documentElement.childNodes( 0 ) : objDoc.documentElement;
}


/**********************************************************

	[function] GetXMLAttribute

	Get an attribute on a XML node in a safe manner.

	[in]	objNode			The node to retrieve the attribute from
	[in]	strName			The name of the attribute

	[return]	The value of the attribute or null

***********************************************************/
function GetXMLAttribute( objNode, strName )
{
	try
	{
		var objItem = objNode.attributes.getNamedItem( strName );
		if ( objItem )
		{
			return objItem.nodeValue;
		}
		else
		{
			return null;
		}
	}
	catch( e )
	{
		// catches lack of attributes
		return null;
	}
}



/**********************************************************

	[function] SetXMLAttribute

	Set an attribute on a XML node in a safe manner.

	[in]	objNode			The node to retrieve the attribute from
	[in]	strName			The name of the attribute
	[in]	strValue		The value of the attribute
	
***********************************************************/
function SetXMLAttribute( objNode, strName, strValue )
{
	objNode.setAttribute( strName, strValue );
}


/**********************************************************

	[function] GetXMLText

	Get the text contained by the node
	
	[in]	objNode			The node holding the text

	[return]	A string containing the text

***********************************************************/
function GetXMLText( objNode )
{
	return objNode ? objNode.text : "";
}



/**********************************************************

	[function] ConvertToXMLCompliantString

	Replaces forbidden characters with XML compliant characters
	
	[in]	strInput			The string to contert

	[return]	The converted string

***********************************************************/
function ConvertToXMLCompliantString( strInput )
{
	strInput = StringReplace( strInput, "&", "&amp;" );
	strInput = StringReplace( strInput, "<", "&lt;" );
	strInput = StringReplace( strInput, ">", "&gt;" );
	
	return strInput;
}


/**********************************************************

	[function] ConvertFromXMLCompliantString

	Replaces converted characters with 'normal' characters
	
	[in]	strInput			The string to contert

	[return]	The converted string

***********************************************************/
function ConvertFromXMLCompliantString( strInput )
{
	strInput = StringReplace( strInput, "&gt;", ">" );
	strInput = StringReplace( strInput, "&lt;", "<" );
	strInput = StringReplace( strInput, "&amp;", "&" );
	
	return strInput;
}