【问题标题】:Javascript: use xpath in jQueryJavascript:在 jQuery 中使用 xpath
【发布时间】:2012-09-03 07:30:57
【问题描述】:

例如,我有下一个 XPath 查询:

//div[span="something"]/parent::div/child::div[@class=\"someClass\"]

我想在 JavaScript 中使用这个 XPath 查询:

return $("a:contains('Fruits')").mouseover();

我试过这个:

return $("div[span=\"something\"]/parent::div/child::div[@class=\"someClass\"]").mouseover();

但它没有用。 XPath 查询是否有另一种语义以便在 JavaScript 中使用它们?

【问题讨论】:

    标签: javascript jquery xpath


    【解决方案1】:

    您可以将现有 XPath 评估的结果添加到 jQuery 选择中,我将这个 jquery 扩展拼凑在一起,似乎可以为您完成所有工作。

    示例用法:

    $(document).xpathEvaluate('//body/div').remove()
    

    这是插件。

    $.fn.xpathEvaluate = function (xpathExpression) {
       // NOTE: vars not declared local for debug purposes
       $this = this.first(); // Don't make me deal with multiples before coffee
    
       // Evaluate xpath and retrieve matching nodes
       xpathResult = this[0].evaluate(xpathExpression, this[0], null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
    
       result = [];
       while (elem = xpathResult.iterateNext()) {
          result.push(elem);
       }
    
       $result = jQuery([]).pushStack( result );
       return $result;
    }
    

    【讨论】:

    • 在 Chrome 中对我不起作用,必须更改 this = this.first();到 $this = $this.first();
    【解决方案2】:

    您可以将 xpath 查询重写为 CSS 选择器:

    $('div:has(> div > span:contains(something)) > div.someClass');
    

    您可以使用:has pseduo 选择器根据其子元素来选择一个元素,从而达到与parent:: 相同的效果:div.foo:has(> div.bar) 将选择所有具有foo 类且具有子@987654331 的div 元素@ 类bar。这相当于div[@class="bar"]/parent::div[@class="foo"]

    见:

    您可以使用各种组合jQuery's DOM traversal methods 以其他几种方式解决此问题。例如,这将是您的 xpath 查询的非常直接的翻译:

    $('div:has(> span:contains(something))')  // //div[span="something"]
        .parent('div')                        // /parent::div
        .children('div.someClass');           // /child::div[@class="someClass"]
    

    值得注意的是,CSS 中的 div.someClass 并不完全等同于 xpath 中的 div[@class="someClass"]。 CSS 将匹配<div class='foo someClass bar'>,但 xpath 不会。详情请参阅Brian Suda's article on parsing microformats with XSLT

    【讨论】:

    • CSS 是否支持 parent::div 子句?
    • 我的 xpath 到 CSS 翻译是错误的,我已经更正了它并解释了 parent::div 是如何复制的。
    • 如果类名中有空格怎么办 - div[@class="bar"]/parent::div[@class="foo bar"]
    【解决方案3】:

    作为Wicked Good XPath的合著者,我当然推荐它来支持跨浏览器的XPath(在HTML文档上,您可以尝试将它与XML文档一起使用,但支持不完整)。

    我们欢迎对我们的库进行任何类型的正确性测试/性能基准测试。在开发过程中,该库已在 IE 7 到 10 以及不支持原生 XPath 的 Android 2.2 浏览器上进行了测试。

    【讨论】:

      【解决方案4】:

      如果你想从父窗口中选择一个 iframe 内的元素,你应该将 evaulate() 函数的第二个参数更改为 iframe 的文档元素,例如:

      var iFrameDocument = $('iframe#myPage').get(0).contentWindow.document;
      xpathResult = this[0].evaluate(xpathExpression, iFrameDocument, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
      

      【讨论】:

        【解决方案5】:

        据我所知,没有跨浏览器实现。 jQuery 有一个xpath plugin,表示仍在开发中。

        除此之外,还有一个由 Google 编写的 DOM Level 3 XPath 规范的纯 JavaScript 实现,称为 wicked-good-xpath,这很好。

        【讨论】:

          【解决方案6】:

          我不确定parent::div 子句,但没有它应该是这样的:

          $('div[span="something"] div.someClass');
          

          【讨论】:

          • 在 xpath div[span="something"] 中选择带有子 span 且文本值为 somethingdiv 元素,它不会寻找 span 属性。我认为您将它与(非常相似的外观)div[@span="something"] 混合在一起。查看示例:w3.org/TR/xpath/#path-abbrev
          【解决方案7】:

          从这里阅读evaluate 方法: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript

          var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );
          

          【讨论】:

            【解决方案8】:

            jQuery 对 XPath 的支持有限。您可以在此处查看它所支持的内容: http://docs.jquery.com/DOM/Traversing/Selectors#XPath_Selectors

            正如@Ameoo 所提到的,您可以使用大多数现代浏览器中都可用的评估方法 - 可以预见的是,IE 除外: jquery select element by xpath

            【讨论】:

              猜你喜欢
              • 2011-04-11
              • 2020-03-11
              • 1970-01-01
              • 2014-02-28
              • 2023-04-07
              • 1970-01-01
              • 2016-07-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多