Create Xml document based on the browser using Javascript - javascript

I am trying to get an older application to work in Chrome and Edge. It currently works only in Compatibility Mode. I have narrowed it down to where it gets the browser type and then creates the xml document based on the browser type.
// Identify and return the browser type
function getBrowserType()
{
try
{
if (typeof ActiveXObject != 'undefined')
{
//Microsoft Internet Explorer
return 'MSIE';
}
else if (typeof document != 'undefined'
&& document.implementation
&& document.implementation.createDocument
&& typeof DOMParser != 'undefined')
{
//Other browsers
return 'OTH';
}
}
catch(ex)
{
alert('Unable to find browser type.\n' + ex.message);
}
}
//create the xml DOM by browser detection
function createDoc(browserType)
{
var xmlDOM = null;
if (browserType == 'MSIE')
{
try
{
var names = [ 'Msxml2.DOMDocument.6.0',
'Msxml2.DOMDocument.3.0',
'MSXML2.DOMDocument',
'MSXML.DOMDocument',
'Microsoft.XMLDOM' ];
for (var key in names)
{
try
{
xmlDOM = new ActiveXObject(names[key]);
}
catch(ex)
{}
}
}
catch(ex)
{
alert('Unable to create XML Document.\n' + ex.message);
}
}
else if (browserType == 'OTH')
{
try
{
xmlDOM = document.implementation.createDocument("", "", null);
}
catch(ex)
{
alert('Unable to create XML Document.\n' + ex.message);
}
}
return xmlDOM;
}
So the object that is created is incorrect and it will not create the xml document. If the object created is the ActiveXObject, in Compatibility Mode, it has no problem. So this is based on the browser. So I basically need a way for this to work in all browsers. I think there may be a better way to do this as this is very old 2009 code.

I have tested your code on my side, it seems that I can't detect the IE browser (I'm using IE 11).
I suggest you could try to detect the browser using the window.navigator.userAgent property. code as below:
if (window.navigator.userAgent.toLowerCase().indexOf("trident") > -1) {
//Microsoft Internet Explorer
return "IE";
}
Because, the Browser Agent strings as below:
[Note] The navigator data can be changed by the browser owner, if the userAgent was not modified, user could use the above method to detect the browser using JavaScript.
Then, you could refer to this article to create XML DOM.

Related

CRM 2015 Microsoft app xpathevaluator' is undefined

We are using crm 2015 and it is working without a problem.
All code is executed correctly in IE and in Chrome.
But when we try to use the crm app from Microsoft we get the error: 'xpathevaluator' is undefined.
I think it is the xrmservicetoolkit that is throwing the error.
if (typeof (node.selectSingleNode) != "undefined") {
return node.selectSingleNode(xpathExpr);
} else {
var xpe = new XPathEvaluator();
var xPathNode = xpe.evaluate(xpathExpr, node, _NSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
return (xPathNode != null) ? xPathNode.singleNodeValue : null;
}

Fall-back support for XMLHTTPRequest

We have a web application that makes use of native XMLHttpRequest() to send data back to our server. One of our larger clients have users that appear to be running IE8 in Win7 (64-bit) and have "Enable native XMLHTTP support" disabled in their browser.
We've implemented the typical scenario of instantiating an ActiveXObject in place of XMLHttpRequest in order to try to support the likes if IE6 (no native XMLHTTP support; yes, we still have clients running this on thin clients!) which I am hoping IE8 can utilise as a fallback if this checkbox option has been switched off. However, once an object has been created, I get a type error when calling open() method on it.
Here's my code:
// Posts back an xml file synchronously and checks for parse error.
// Returns xml object or null. Used in RSUserData.
XML.PostXmlFile = function(sURL, doc)
{
try
{
// Validate Input
if ((typeof (sURL) != "string") || (sURL == ""))
return null;
if (window.XMLHttpRequest) // IE7+, FF and Chrome
{
// Mozilla, create a new DOMParser and parse from string
// Although IE9 and IE10 can successfully load XML using this block, it can't use document.evaluate nor selectNodes/selectSingleNode to navigate it
// Ref: http://msdn.microsoft.com/en-us/library/ie/ms535874(v=vs.85).aspx
// Ref: http://msdn.microsoft.com/en-us/library/ie/ms534370(v=vs.85).aspx
// Ref: http://blogs.msdn.com/b/ie/archive/2012/07/19/xmlhttprequest-responsexml-in-ie10-release-preview.aspx
var req = new XMLHttpRequest();
req.open("post", sURL, false);
req.send(doc);
if (req.status != 200)
throw { message: 'HTTP Post returned status ' + req.status + ' (' + req.statusText + ') when sending to ' + sURL };
// IE11+: req.responseXML returns a native XML Document
// IE9/10: req.responseXML returns an IXMLDOMDocument2 object but we can convert req.responseText to native XML using DOMParser
// IE6/7/8: req.responseXML returns an IXMLDOMDocument2 object but DOMParser is not available
if (window.DOMParser)
{
var parser = new DOMParser();
return parser.parseFromString(req.responseText, 'application/xml');
}
else
return req.responseXML; // NATIVE
}
else
{
// up to IE6:
// Ref: http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
var oXML = XML.GetActiveX_XML();
if (!oXML)
throw { message: "Could not instantiate an Msxml2 ActiveXObject", innerException: e };
oXML.open('POST', sURL, true);
oXML.send(sFile);
if (oXML.parseError.errorCode == 0)
{
xmlDoc = oXML;
return xmlDoc;
}
return null;
}
}
catch (e)
{
var s = "Exception in XML.PostXmlFile(). " + (e.message ? e.message : "");
throw { message: s, innerException: e };
}
}
XML.GetActiveX_XML = function()
{
var progIDs = ['Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.3.0'];
for (var i = 0; i < progIDs.length; i++)
{
try
{
var oXML = new ActiveXObject(progIDs[i]);
var sl = oXML.getProperty("SelectionLanguage");
if (sl !== "XPath")
oXML.setProperty("SelectionLanguage", "XPath"); // Changes v3.0 from XSLPattern to XPath
var ns = "xmlns:rs='" + XML._nsResolver('rs') + "' xmlns:xsi='" + XML._nsResolver('xsi') + "'";
// ns = "xmlns:na='http://myserver.com' xmlns:nb='http://yourserver.com'";
oXML.setProperty("SelectionNamespaces", ns);
return oXML;
}
catch (ex) { }
}
return null;
}
NOTES:
The aim is to call to XML.PostXmlFile() with the url and payload.
Modern browsers use new XMLHttpRequest() as expected
IE6 is expected to use XML.GetActiveX_XML() on account that window.XMLHttpRequest returns falsey
IE8 with "Enable native XMLHTTP support" disabled falls through to the IE6 code (because window.XMLHttpRequest returns falsey) but the instantiated object fails because it doesn't support open() method (oXML.open('POST', sURL, true);)
Is there any way I can post my payload back using IE8 when "Enable native XMLHTTP support" is disabled?
You should see if the Microsoft.XMLHTTP is available before checking if there is a XMLHttpRequest:
var bActiveX;
try {
new ActiveXObject('Microsoft.XMLHTTP');
bActiveX = true;
}
catch(e) {
bActiveX = false;
}
And then, check in your if condition:
if (window.XMLHttpRequest || bActiveX) { // IE7+, FF and Chrome
var req = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
/* the rest of your code */
}

IE11 not recognizing .loadXML()

Working on some xml data and my function works in all browsers except for IE10 and up.
Is there something else I can use instead of .loadXML(data)
Here is part of the transform function. it breaks at x.loadXML(data)
$.transform = function(o) {
var createXmlObj = function(data) {
if($.browser.msie) {
var x = $("<xml>")[0];
x.loadXML(data);
return x;
} else {
var parser = new DOMParser();
return parser.parseFromString(data,"text/xml");
}
};
add your page to Internet Explorer's Compatibility View Settings. You won't believe the types of issues that this fixes.

transformNode function for ie9

I need to transform an xml doc into another xml doc using xslt in ie9 or above versions.
I am trying to transform an xml doc using xslt in ie9. When i used transformNode() function it is working fine in ie8(code:: resultDocument = XML.transformNode(XSL);) but in ie9 transformNode function is not defined showing error::SCRIPT438: Object doesn't support property or method 'transformNode'
I found a solution for ie9 as given below
if (window.ActiveXObject) {
console.log('inside hi');
var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
xslDoc.loadXML(xsltDoc.xml);
console.log(xslt.styleSheet);
xslt.stylesheet = xslDoc;
var xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.transform();
return xslProc.output;
}
but when i run this i get an error: SCRIPT16389: The stylesheet does not contain a document element. The stylesheet may be empty, or it may not be a well-formed XML document.
I am new to javascript/jquery. Can anyone please help me in resolving this. If there is any other function either in javascript or jquery it would be helpful.
Thanks in advance
With earlier versions of IE the responseXML document used to be an MSXML DOM document and MSXML implements XSLT and transformNode. With newer IE versions the responseXML document gives you an IE DOM document and IE does not implement XSLT and transformNode for its DOM document/nodes. Nor does an IE DOM document have a property xml you are trying to use in xslDoc.loadXML(xsltDoc.xml);.
Try changing that part of the code to
if (typeof XMLSerializer !== 'undefined') {
xslDoc.loadXML(new XMLSerializer().serializeToString(xsltDoc));
// now use xslDoc here
}
A different option is to use xslDoc.loadXML(xmlHttp.responseText); if you still have access to the XMLHttpRequest. There is also an option to ensure you get an MSXML responseXML, see try { xhr.responseType = 'msxml-document'; } catch(e){} line in http://blogs.msdn.com/b/ie/archive/2012/07/19/xmlhttprequest-responsexml-in-ie10-release-preview.aspx.
Your whole approach to object checking in your code is wrong, check for the object or property or method you want to use (e.g. if (typeof XSLTProcessor !== 'undefined') { // now use XSLTProcessor here }), not for completely different object like document.implementation.
I too had the SCRIPT16389: The stylesheet does not contain a document element. The stylesheet may be empty, or it may not be a well-formed XML document error in IE9/10/11. I've found the following fixes it:
your code:
if (window.ActiveXObject) {
console.log('inside hi');
var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
xslDoc.loadXML(xsltDoc.xml);
console.log(xslt.styleSheet);
xslt.stylesheet = xslDoc;
var xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.transform();
return xslProc.output;
}
working code:
if (window.ActiveXObject) {
console.log('inside hi');
var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
xslDoc.load(xsltDoc);
console.log(xslt.styleSheet);
xslt.stylesheet = xslDoc;
var xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.transform();
return xslProc.output;
}
The change being line 6 - replace 'loadXML' with 'load' and 'xsltDoc.xml' with just 'xsltDoc'. Let me know how it goes!

How do I transform an XML document using XSLT and add a parameter in IE?

I'm new to learning XSLT, and I've come across something I really don't quite understand. I need to add an XSLT parameter before transforming the document. I can do this for non-IE browsers like so:
function loadXMLDoc(dname) {
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET", dname, false);
xhttp.send("");
return xhttp.responseXML;
}
function displayResult() {
xml = loadXMLDoc("cdcatalog.xml");
xsl = loadXMLDoc("cdcatalog.xsl");
// code for IE
if (window.ActiveXObject) {
ex = xml.transformNode(xsl);
document.getElementById("example").innerHTML = ex;
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument) {
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml, document);
document.getElementById("example").appendChild(resultDocument);
}
}
Now, I can do it for non-IE browsers, a new XSLT Processor object is made, stylesheet imported, and you simply add the parameter before the transformation process. None of this seems to be happening for the IE version of the code though, and I can't simply add the parameter before the transformation. I've googled profusely and seen different things telling me to create new ActiveX objects of various different MSXML versions, and I'm deeply confused by the whole affair.
Taking the above code, how do I do this:
xsltProcessor.setParameter(null,"PARAMNAME","PARAMVALUE");
except for IE and if possible, can someone explain how IE deals with the whole concept of XSLT differently to FF/O/C/other civilised browsers?
You might try using Sarissa, which is an abstraction layer that provides a cross-browser XSLT transformation API.
According to this page, you can use
XSLTProcessor.addParameter("Parameter Name", "Parameter Value");
where XSLTProcessor is created with
var XSLTCompiled = new ActiveXObject("MSXML2.XSLTemplate");
XSLTCompiled.stylesheet = XSL.documentElement;
var XSLTProcessor = XSLTCompiled.createProcessor();
The transform call is also different.
XSLTProcessor.transform();
Anyway, it looks like there's a quite elaborate explanation of what you're asking for.
I did cross-browser XSLT transforms a while back, and here's the code I used. createDocument is just a function to return a DOM document. I didn't do stylesheet parameters, so maybe this is a little off-topic, but anyway it works on IE6+ and Firefox 1.5+.
// arguments can be string (uri of document) or document node
function xslTransform( content, transform, options )
{
if ("string" == typeof content) content = createDocument( content );
if ("string" == typeof transform) transform = createDocument( transform );
var targetEle;
if (options && options.target) targetEle = document.getElementById(options.target);
if (targetEle && options.replace)
while (targetEle.hasChildNodes())
targetEle.removeChild( targetEle.firstChild );
if (window.XSLTProcessor)
{
var processor = new XSLTProcessor();
processor.importStylesheet( transform );
var frag = processor.transformToFragment( content, document );
if (targetEle)
targetEle.appendChild( frag );
}
else if (window.ActiveXObject)
{
if (targetEle)
targetEle.innerHTML = content.transformNode( transform );
}
else return "XSLT not supported";
}

Categories

Resources