IE中的XPath查询使用从零开始的索引,但W3C规范是基于一的.我该如何处理差异?

hug*_*omg 6 javascript internet-explorer xpath cross-browser

问题

我正在转换一个相对较大的Javascript,目前只能在Internet Explorer上运行,以使其在其他浏览器上运行.由于代码广泛使用XPath,我们提供了一些兼容性功能,使事情变得更容易

function selectNodes(xmlDoc, xpath){
    if('selectNodes' in xmlDoc){
        //use IE logic
    }else{
        //use W3C's document.evaluate
    }
}
Run Code Online (Sandbox Code Playgroud)

这大部分工作正常但我们只是遇到了IE中的位置从零开始的限制,但在其他浏览器使用的W3C模型中,它们是基于单一的.这意味着要获得我们需要//books[0]在IE和//books[1]其他浏览器中执行的第一个元素.

我建议的解决方案

第一个想法是使用正则表达式向查询中出现的所有索引添加一个,如果我们使用document.evaluate版本:

function addOne(n){ return 1 + parseInt(nStr, 10); }

xpath = xpath.replace(
    /\[\s*(\d+)\s*\]/g,
    function(_, nStr){ return '[' + addOne(nStr) + ']'; }
);
Run Code Online (Sandbox Code Playgroud)

我的问题

这种基于正则表达式的解决方案是否相当安全?

  • 有什么地方可以转换它不应该的东西吗?
  • 是否有任何地方不会转换它应该的东西?

例如,它将无法替换索引,//books[position()=1]但由于IE似乎不支持position()我们的代码没有使用,我认为这种特殊情况不会成为问题.


注意事项

  • 我下载了Sarissa,看看他们是否有办法解决这个问题,但看了源代码后他们显然没有?

  • 我想在W3C版本中添加一个,而不是在IE版本中减去一个以减轻我的转换工作量.


到底

我们决定通过设置选择语言来重写代码以在IE中使用适当的XPath

xmlDoc.setProperty("SelectionLanguage", "XPath");
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 8

我们刚刚遇到IE中的位置从零开始的限制,但在其他浏览器使用的W3C模型中,它们是基于单一的.这意味着要获得我们需要//books[0]在IE和//books[1]其他浏览器中执行的第一个元素.

在进行任何XPath选择之前,请指定:

xmlDoc.setProperty("SelectionLanguage", "XPath");
Run Code Online (Sandbox Code Playgroud)

MSXML3使用在XSLT和XPath成为W3C Recommendations之前使用的XSLT/XPath方言.默认为"XSLPattern",这就是您所看到的行为.

在这里阅读更多关于这个主题:

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