How do you run an xPath query in IE11? - javascript

At one point in our system we use javascript to read in a chunk of XML and then query that XML document using xPath.
Prior to IE 11, IE supported using xmldoc.selectSingleNode(“//xpath/string”) and the non IE browsers supported using a xmldoc.evaluate(“//xpath/string”). These both returned a similar object that we could then carry on interpreting to extract the data required.
In IE11 neither of these methods seem to be available.
It seems that IE11 has some support for XML documents in that when I read in the xml using the DOMParser object using the parseFromString method, it returns an object that the IE11 debugger calls an XMLDocument.

Thanks to #Martin Honnen for pointing out that some ActivXObjects are still supported in IE11!
var doc;
try {
doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(stringVarWithXml);
var node = doc.selectSingleNode('//foo');
} catch (e) { // deal with case that ActiveXObject is not supported }
I've used "Microsoft.XMLDOM" as it is sugested here that it is a more generic call to what ever xml parser is present on the system, where as it sounds like "Msxml2.DOMDocument.6.0" will fail if that exact version is not present. (We do have to support all IE vers back to 6.0 at my place!)
This just works as it always has done. The only problem I had was that the old switch I used to detect IE vs other browsers was if (typeof ActiveXObject !== "undefined") failed as I guess they are trying to discourage it's use!
Thanks all for your help.

To expand on pixelmatt's answer, some results of my tests (Win 7 64bit with IE11) I did in order to get DOMParser to work as it did in IE9 and IE10 (in IE11 it now returns an XMLDocument object which appears to not support xpath queries?).
Turns out I could make it behave like in IE10 with the following meta tag:
<meta http-equiv="X-UA-Compatible" content="IE=10" />
Results without and with above meta:
And here are the XMLDocument's memebers (for reference):

Related

IE 11 AngularJS error - Object doesn't support property or method 'from'

In my JavaScript I have a function detectEnvironmentAndGetLEAndDepot() which is called onload via HTML. I'm working with wicket, and need to take values held in the back-end, so I fire them to the screen, hide them, and search the <span> values from my JS for the name value, for example if(v.getAttribute('name') === 'LE'){do stuff} or if(v.getAttribute('name') === 'depot'){do stuff} (I'm sure not the most elegant solution, but I needed a quick one!). Then within the function detectEnvironmentAndGetLEAndDepot() I do a bit of formatting etc so the data is usable.
detectEnvironmentAndGetLEAndDepot() function (quite long, only relevant part) -
detectEnvironmentAndGetLEAndDepot = function() {
Array.from(document.getElementsByTagName('span')).forEach(function(v) {
//Search name tag for particular names, then do formatting
}
When I open this in IE11 I get the error in a popup SCRIPT438: Object doesn't support property or method 'from' which is related to the first line of the method above - the Array class. Help much appreciated.
As Array.from method is not supported by IE, you can try to use:
[].slice.call(document.getElementsByTagName('span')).forEach(function(v) {});
This doesn't require usage of any 3rd party libraries.
You could use an ES2015 polyfill, like es6-shim, Array.from or Babel polyfill
As explained by Mozilla here, the Array.from function is not yet supported by IE
you can use instead _underscore.js with function _.toArray(document.getElementsByTagName('span'))...
FYI:
'Array.from' not supported in the following document modes: Quirks, Internet
Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer
8 standards, Internet Explorer 9 standards, Internet Explorer 10
standards, Internet Explorer 11 standards. Not supported in Windows
8.1.
source

dojo.exists fails with IE11

Since a few days, I have troubles with Internet Explorer 11 in conjunction with dojo toolkit 1.9.4 hosted by a Domino Server.
Source Code:
if (dojo.exists("btnUpload")) {
console.log("btnUpload exist ... do something...");
} else {
console.log("btnUpload doesn't exist...");
}
With IE11 the return value of dojo.exists() is always false!
IE11 Debugger:
However in all other browser (Mozilla Firefox, Google Chrome, Apple Safari) it works!
Using dojo.exists for this isn't very appropriate, given that btnUpload is technically just a DOM ID, and not an actual object in the global scope. if (document.getElementById('btnUpload')) would seem to be far more appropriate in this case.
When a global reference is encountered that doesn't match an actual global variable, but does match a DOM ID, browsers tend to return the DOM node, but I wouldn't recommend relying upon that.

Parse HTML retrieved via AJAX in JavaScript

I'm attempting to write some JavaScript code (in particular, a Chrome extension) which does the following:
Retrieve some web page's contents via AJAX.
Get some content from that page by locating certain elements inside of the HTML string and getting their contents.
Do a thing with that data.
I have 1) and 3) working, but I'm having some trouble achieving step 2) in a reasonable way.
I currently have 2) implemented via jQuery(htmlString) and then using normal jQuery selectors and etc. to extract the data I want. The problem is that jQuery actually adds the retrieved HTML to the current page, loading and executing all external resources / scripts in the process. This is obviously bad.
So I'm looking for a way to get the text and HTML in certain tags inside my HTML string without:
Loading or executing ANY scripts or resources (images, CSS, etc.) referenced in the HTML string.
Trying to remove external resources with regular expressions, since we all know what happens when you parse [X]HTML with regex.
I believe that I can achieve what I want using jsdom and jQuery, since jsdom has a FetchExternalResources option which can be set to false. However, jsdom seems to only work in NodeJS, not in the browser.
Is there any reasonable way to do this?
You could use document.implementation.createHTMLDocument
This is an experimental technology
Because this technology's
specification has not stabilized, check the compatibility table for
the proper prefixes to use in various browsers. Also note that the
syntax and behavior of an experimental technology is subject to change
in future versions of browsers as the spec changes
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) 4.0 (2.0) [1] 9.0 (Yes) (Yes)
[1] The title parameter has only been made option in Firefox 23.
Javascript
$.ajax("http://www.html5rocks.com/en/tutorials/").done(function (htmlString) {
var doc = document.implementation.createHTMLDocument("");
doc.write(htmlString);
console.log(doc.getElementById('siteheader').textContent);
});
On jsFiddle
You can also take a look at DOMParser and XMLHttpRequest
Example using XMLHttpRequest
XMLHttpRequest originally supported only XML parsing. HTML parsing
support is a recent addition.
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Support 18 11 10 --- Not supported
Javascript
var xhr = new XMLHttpRequest();
xhr.onload = function () {
console.log(this.responseXML.getElementById('siteheader').textContent);
};
xhr.open("GET", "http://www.html5rocks.com/en/tutorials/");
xhr.responseType = "document";
xhr.send();
On jsFiddle

Method compareDocumentPosition unsupported only in IE9

In one of my web pages, I am using the following line of JavaScript:
return !!(a.compareDocumentPosition(b) & 16);
However, only in IE9, I am getting the following error:
Object doesn't support property or method 'compareDocumentPosition'
Other browsers work fine. Does anyone know of an available fix or workaround for this?
Internet Explorer supports compareDocumentPosition only in IE9 mode. Make sure you have at the beginning of your markup and document.documentMode returns 9

running an XPath expression SVG inside an HTML with javascript

I'm trying to run an xpath-expression over an svg which is embedded in html. I just cannot figure out how to set up the parameters. I want find elements that have an arbitary attribute from a given namespace. I use the following xpath expression:
var xpathexp = "//*[#*[namespace-uri()='"+this.typo7namespace+"']]";
I tested this expression and it worked as expected.
this is the code to find the result set:
var result = this.svgdocument.contentDocument.evaluate( xpathexp, this.svgdocument.documentElement, null, XPathResult.ANY_TYPE, null );
Could anybody tell me, or post a link to a tutorial, how to deal with the namspaces, the namespace resolvers??
Greetings...
Here's the Mozilla tutorial on using XPath:
https://developer.mozilla.org/en/Introduction_to_using_XPath_in_JavaScript
Here's one on writing custom namespace resolvers:
https://developer.mozilla.org/en/Introduction_to_using_XPath_in_JavaScript#Implementing_a_User_Defined_Namespace_Resolver
I found these interfaces to be rather clunky, though, so I wrote an abstraction layer that would take the xpath string and a context node, and would return a regular js array. It works inside the browser and embedded in Java under Mozilla Rhino:
https://svn.apache.org/repos/asf/commons/sandbox/gsoc/2010/scxml-js/trunk/src/javascript/scxml/cgf/util/xpath.js
All of the above should work in all browsers except for IE6-9.
IE6-8 does not support SVG natively, so this should be less important to your question. For completeness, though, here's a good article describing XPath support in earlier IE8, including support for resolving namespaces:
http://www.nczonline.net/blog/2009/04/04/xpath-in-javascript-part-3/
Apparently, IE9 also does not include support for XPath in the browser, which is more problematic, as it does support SVG natively. Probably the best approach here is to use ActiveX to work with MSXML APIs:
IE9 selectSingleNode missing from beta, how to overcome this in JavaScript?

Categories