XPath queries in IE use zero-indexes, but the W3C specification is unidirectional. How should I deal with the difference?

Problem

I am converting a relatively large piece of Javascript that currently only works in Internet Explorer to make it work with other browsers as well. Since XPath is used in the code, we made a small compatibility function to make things easier

function selectNodes(xmlDoc, xpath){ if('selectNodes' in xmlDoc){ //use IE logic }else{ //use W3C document.evaluate } } 

This basically works fine, but we just came across a limitation that the positions in IE are based on zero, but in the W3C model used by other browsers, they are based on one . This means that to get the first element we need to do //books[0] in IE and //books[1] in other browsers.

My proposed solution

The first thought was to use a regular expression to add one to all the indexes that appear in queries if we use the version of document.evaluate:

 function addOne(n){ return 1 + parseInt(nStr, 10); } xpath = xpath.replace( /\[\s*(\d+)\s*\]/g, function(_, nStr){ return '[' + addOne(nStr) + ']'; } ); 

My question

Is this regex-based solution safe?

  • Are there any places in which he will convert what he should not do?
  • Are there places where he will not convert something that is needed?

For example, it cannot replace the index in //books[position()=1] , but since IE does not support position() and our code does not use it, I think this particular case will not be a problem.


Questions

  • I downloaded Sarissa to find out if they have a way to solve this problem, but by looking at the source code, obviously they donโ€™t?

  • I want to add it to the W3C version instead of subtracting it in the IE version to facilitate my conversion.


In the end

We decided to rewrite the code to use proper XPath in IE by setting the language of choice

 xmlDoc.setProperty("SelectionLanguage", "XPath"); 
+6
source share
2 answers

we just came across a limitation that the positions in IE are zero based but in the W3C model used by other browsers, they are unidirectional. This means that to get the first element we need to do //books[0] in IE and //books[1] in other browsers.

Before making any XPath selection, specify :

 xmlDoc.setProperty("SelectionLanguage", "XPath"); 

MSXML3 uses the XSLT / XPath dialect that was used before XSLT and XPath became W3C Recommendations . The default is XSLPattern, and this is what you see as a behavior.

Read more about this here:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms754679 (v = vs .85) .aspx

+8
source

Why not change the original expressions to this:

 var expr = "books[1]"; 

... becomes:

 var expr = "books[" + index(1) + "]"; 

... where index is defined as (pseudocode):

 function index(i) { return isIE ? (i - 1) : i; } 
+1
source

Source: https://habr.com/ru/post/904320/


All Articles