【问题标题】:Selenium, xpath to match a table row containing multiple elementsSelenium, xpath 匹配包含多个元素的表行
【发布时间】:2010-10-27 20:11:03
【问题描述】:

我正在尝试找到一个 Selenium/PHP XPath 来匹配包含多个元素(文本和表单元素)的表行。

例子:

<table class="foo">
  <tr>
    <td>Car</td><td>123</td><td><input type="submit" name="s1" value="go"></td>
  </tr>
</table>

这适用于单个文本元素:

$this->isElementPresent( "//table/tbody/tr/td[contains(text(), 'Car')]" );

虽然这不是(省略 /td 定位器):

$this->isElementPresent( "//table/tbody/tr[contains(text(), 'Car')]" );

因此,这显然不适用于多个元素:

$this->isElementPresent( "//table/tbody/tr[contains(text(), 'Car')][contains(text(), '123')]" );

另一种方法是使用getTable( "xpath=//table[@class='foo'].x.y") 处理每一行 x 和 y 列。很麻烦,但它起作用了……主要是。它不会返回 &lt;input&gt; 标签!它将为该单元格返回一个空字符串:(

有什么想法吗?

【问题讨论】:

    标签: php selenium xpath html-table row


    【解决方案1】:

    这个XPath 表达式:

    /html/body/table[descendant::td[contains(.,'Car')]]

    注意:如果您知道自己的架构,请不要使用开头的 // 运算符。使用字符串值而不是文本节点(这样可以得到所有后代文本节点的连接)。

    【讨论】:

    • 虽然这可能有效,但我不喜欢使用完整的模式,它的灵活性较低(例如,如果另一个开发人员在我的表格之前的页面上添加了一些东西,xpath 就会中断)。它也不能解决我原来匹配包含多个指定元素的行的问题。
    • @foob.ar:这就是为什么我的句子以If you know your schema 开头...你的问题是使用text() 而你的问题是Any ideas ?。如果您知道如何进行概括,则可以对其进行修改。您希望td 容器不同还是相同?
    【解决方案2】:

    可以将多个路径与 | 组合使用分隔器。 调整这个:

    //tr/td[contains(text(), 'Car')]/text()  | //tr/td/input[@value="s1"]/@name
    

    【讨论】:

      【解决方案3】:

      你可能想使用

      //td[contains,'Car'] 和 td[contains,'123']/ancestor::tr

      这将选择包含与两个包含参数匹配的 td 的 tr

      尝试在firefox中使用View Xpath Plugin,非常有用的插件。

      了解有关 Xpath 中轴的更多信息:http://www.w3schools.com/xpath/xpath_axes.asp

      【讨论】:

      • 谢谢,这似乎可以根据需要工作!是的,这个 firefox 插件很好,虽然它不会吐出灵活的 xpath - 正如我在对 Alejandro 的其他评论中所说,如果在我的表格之前的页面中添加了某些内容,xpath 将会中断。
      • 语法未经测试,错误见谅。我怀疑这会破坏 xpath,因为 xapth 选择一个元素 1- td a 和 b 的内容,与表格的位置以及它前面或后面的内容无关。希望我做对了..
      【解决方案4】:

      感谢 knb 提供一些语法提示。 这有点离题,但与将我带到这里的搜索相关......

      我有一张带有 [ 名称 |值] 单元格。我需要从前面带有“名称”的行中获取值。

      (假的例子,但我正在寻找的每个链接都有相同的文本并且没有 ID - 关键是上下文信息在相邻的单元格中)

      <table id="options"><tbody>
      <tr>
       <td>other</td>
       <td><a href="#clicky">edit</a></td>
      </tr>
      <tr>
       <td>this label</td>
       <td><a href="#clicky">edit</a></td> <!-- I want this button -->
      </tr>
      <tr>
       <td>other</td>
       <td><a href="#clicky">edit</a></td>
      </tr>
      </tbody></table>
      

      我可以这样检索我想要的按钮,使用嵌套的 [[]] 条件:

      //table[@id='options']/tbody/tr[td[contains(text(), 'this label')]]/td[2]/a

      “获取包含另一个单元格的行中的“a”,其中包含我要查找的文本”

      我认为这种任务可能很常见,所以我在这里发布它以供参考

      【讨论】:

        【解决方案5】:

        在我的问题中,我有一个产品列表,该列表由唯一的 SKU/目录组合标识。如果我想将该产品添加到购物车,我会按 SKU 和目录进行选择。

        使用 foob.ar 的例子:

        //table[@class='foo']/tr[td[contains(text(), 'Car')] and td[contains(., '123')]]
        

        您可以将它与 dman 的解决方案结合使用,以在该行中选择特定元素/列

        //table[@class='foo']/tr[td[contains(text(), 'Car')] and td[contains(., '123')]]//input[@name='s1']
        

        编辑:

        如果我只在任何列中查找这两个值,则上述解决方案有效。如果你想找到一个相对于特定列的值,我不得不稍微修改一下

        //table[@class='foo']/tr[td[position()=1 and contains(text(), 'Car')] and td[position()=2 and contains(text(), '123')]]//input[@name='s1']
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-26
          • 2014-02-02
          • 2016-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多