【问题标题】:Different results selecting HTML elements with XPath in Firefox and Internet Explorer在 Firefox 和 Internet Explorer 中使用 XPath 选择 HTML 元素的不同结果
【发布时间】:2008-10-07 11:23:45
【问题描述】:

我正在尝试在文档中选择一个特定的 HTML 元素,对于我只使用的 firefox:

xpathobj = document.evaluate(xpath, document, null,
               XPathResult.FIRST_ORDERED_NODE_TYPE, null);

效果很好。但是,当我尝试 IE 等效项时:

xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.load(document);
xmlDoc.setProperty("SelectionLanguage", "XPath");
xpathobj = xmlDoc.selectNodes(xpath);

我没有返回任何对象。所以我的问题是有一种简单的方法可以使用 XPath 在 IE 中获取我想要的元素吗? 我使用的 XPath 看起来像

/HTML/BODY/DIV[9]/DIV[2]

【问题讨论】:

    标签: javascript internet-explorer xpath


    【解决方案1】:

    看看http://dev.abiss.gr/sarissa/ 项目。他们已将大部分与 XML 相关的 API 迁移到 IE。 否则它确实也很容易实现。您需要解决的问题是:将 HTML 序列化为有效的 XML,将 XMLDOM XPath 查询的结果与原始 HTMLDOM 同步。据我所知,他们已经在他们的库中完成了这项工作,但是,它的性能本来可以更好。

    【讨论】:

      【解决方案2】:

      问题可能在于 IE5+ 中的 [1] 实际上是 FF 中的 [2]。 Microsoft 仅决定编号应从 [0] 开始,而不是 w3c 指定的 [1]。

      【讨论】:

        【解决方案3】:

        嗨,最后我想出了自己的狡猾的解决方案,任何关于改进它的建议都会非常感激。它利用了一些原型功能:

        在 IE5+ 中工作,xpath 格式为“/HTML/BODY/DIV[9]/DIV[2]”

        function getXPathElement (xpath , element) {

        //Specific to project, here i know that the body element will always have the id "top"
        //but otherwise the element that is passed in should be first element in the xpath 
        //statement eg. /HTML/BODY/DIV the element passed in should be HTML
        if(!element){
            element = $("top");
            var xpathArrayIndex = 3;
        } else {
            var xpathArrayIndex = 1;
        }
        //split the xpath statement up
        var xpathArray = xpath.split("/");
        
        var carryOn = true; 
        while(carryOn){
            decendents = element.childElements();
            //check to see if we are at the end of the xpath statement
            if(xpathArrayIndex == xpathArray.length){
                return element;
            }
            //if there is only one decendent make it the next element
            if(decendents.size() == 1) {
                element = decendents.first();
            } else {
            //otherwise search the decendents for the next element
                element = getXPathElementByIndex(decendents, xpathArray[xpathArrayIndex]);
            }
            xpathArrayIndex++;
        }
        

        }

        函数 getXPathElementByIndex(decendents, xpathSegment){

        var decendentsArray = decendents.toArray();
        //seperate the index from the element name
        var temp = xpathSegment.split("[");
        var elementName = temp[0];
        //get the index as a number eg. "9]" to 9
        var elementIndex = +temp[1].replace("]", "");
        //the number of matching elements
        var count = 0;
        
        //keeps track of the number of iterations
        var i = 0;
        while(count != elementIndex) {
            //if the decendent's name matches the xpath element name increment the count
            if(decendentsArray[i].nodeName == elementName){
                count++;
            }
            i++;
        }
        var element = decendentsArray[i - 1];
        return element;
        

        }

        感谢大家的帮助,无论哪种方式,我都对各种 javascript 框架有了一些了解。

        【讨论】:

          【解决方案4】:

          oly1234的代码有一些bug我尝试修复如下:

          function getXPathElement(xpath, element){
          if(!element){
              element = document;
          }
          var xpathArray = xpath.split("/");
          
          element = findXPathRoot(xpathArray[0],xpathArray[1],element);
          
          for(var i=1; i<xpathArray.length; i++){
              if(xpathArray[i].toLowerCase()=="html"){
                  continue;
              }
              if(!element){
                  return element;
              }
              element = getXPathElementByIndex(element.childNodes,xpathArray[i]);         
          }
          return element;
          }
          
          
          function findXPathRoot(rootPath,htmlPath,element){
          if(rootPath == ""&&htmlPath.toLowerCase() == "html"){
              return element.documentElement;
          }
          return document.getElementsByTagName(rootPath)[0];
          }
          function getXPathElementByIndex(decendents, xpathSegment){
          //seperate the index from the element name
          var temp = xpathSegment.split("[");
          var elementName = temp[0];
          //get the index as a number eg. "9]" to 9
          if(temp[1]){
              var elementIndex = temp[1].replace("]", "");
          }else{
              var elementIndex = 1;
          }
          //the number of matching elements
          var count = 0;
          for(var i=0;i < decendents.length; i++){
              if (decendents[i].nodeName.toLowerCase() == elementName.toLowerCase()) {
                  count++;
                  if(count==elementIndex){
                      return decendents[i];
                  }
              }
          }
          return null;
          }
          

          【讨论】:

            【解决方案5】:

            您确定在您的 Internet Explorer 版本中实现了 X-Path?如:您使用的是什么版本?

            【讨论】:

              【解决方案6】:

              jQuery 实现了a cross-browser-compatible subset of xPath selectors with a plug-in。您的示例“/HTML/BODY/DIV[9]/DIV[2]”应该可以在其中工作。

              (编辑 - 谢尔盖·伊林斯基更正)

              【讨论】:

              • jQuery 不实现 XPath。它实现了一个非常简单的路径选择功能(大约是 XPath 的 0.01%)
              【解决方案7】:

              而不是做

              xmlDoc.load(document); 
              

              试试

              xmlDoc.loadXML(document.body.outerHTML)
              

              这只有在您的 HTML 文档被格式化为 XHTML 标准时才真正起作用。此外,BODY 标记将是根节点,因此您必须将 XPATH 更改为“/BODY/DIV[9]/DIV[2]”

              【讨论】:

                【解决方案8】:

                我有点担心像这样使用 xml,因为您无法确定一个人拥有的 XML DLL 的版本(如果有的话)。仍然有公司成群结队地使用 IE5.0,而 5.5 有一个特别复杂的 XML 实现。

                【讨论】:

                  【解决方案9】:

                  W3C Dom Level 3 XPath 的另一个 JavaScript 实现可以在 on Source Forge 找到。但似乎不活跃。

                  【讨论】:

                    【解决方案10】:

                    我找不到一个简单通用的解决方案,你可以编写自定义函数来实现一点xpath,但在internet explorer 6或更低版本中很难完成......

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-03-02
                      • 2016-06-13
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-06-19
                      • 2019-08-22
                      相关资源
                      最近更新 更多