【问题标题】:Is it possible to get an input's value using xpath to search on the value of corresponding label?是否可以使用 xpath 搜索相应标签的值来获取输入值?
【发布时间】:2013-03-05 16:04:42
【问题描述】:

鉴于此 HTML 标记:

<tr>
  <td class="label">Description</td>
  <td class="data"><div>QA Test Customer</div></td>
</tr>

尝试编写一个 Ruby 方法,该方法将采用两个参数“Description”和“QA Test Customer”,并使用 Selenium WebDriver 和 XPath 断言带有标签“Description”的输入值实际上是“QA Test Customer” .

不熟悉 xpath,所以我很挣扎。我知道我需要一个 xpath 字符串:

"find a <td> with class of 'label' that has a value of 'Description' then get the value of the <div> embedded in the following <td> with class of 'data'

任何指针都非常感谢!

【问题讨论】:

    标签: ruby xpath selenium-webdriver


    【解决方案1】:
    //td[@class='label' and .='Description']/following-sibling::td[@class='data']/div
    

    【讨论】:

    • 详细说明wst的回答,.='Description'也可以写成text()='Description'这里的.叫做上下文节点,或者有索引的节点
    • 我确定我做错了什么……但我无法使 xpath 查询工作。有什么想法吗?
    • @DangerAngell 如果您可以在问题中添加更大的代码 sn-p 以演示如何调用它,这将有助于确定问题。我不认为它与 xpath 相关。
    【解决方案2】:

    这是为 Nokogiri 写的。我不知道 Selenium 是使用 Nokogiri 还是它自己的 XML 解析器,所以它可能无济于事......

    我更喜欢 CSS,因为它通常不那么冗长且更容易理解:

    require 'nokogiri'
    
    doc = Nokogiri::HTML(<<EOT)
    <tr>
      <td class="label">Description</td>
      <td class="data"><div>QA Test Customer</div></td>
    </tr>
    EOT
    
    doc.at('td.label + td.data').text
    => "QA Test Customer"
    
    doc.at('td.label + td.data').text == 'QA Test Customer'
    => true
    

    这只是寻找第一个&lt;td class="label"&gt;,然后是它的兄弟&lt;td class="data"&gt;,但我们也可以添加搜索文本:

    !!doc.at(%Q/td[class="label"]:contains("Description") + td[class="data"] div:contains("QA Test Customer")/)
    => true
    

    把它变成你可以调用的方法变成:

    def td_match(doc, s1, s2)
      !!doc.at(%Q/td[class="label"]:contains("#{ s1 }") + td[class="data"] div:contains("#{ s2 }")/)
    end
    

    并在 IRB 中调用它:

    irb(main):024:0> def td_match(doc, s1, s2)
    irb(main):025:1>     !!doc.at(%Q/td[class="label"]:contains("#{ s1 }") + td[class="data"] div:contains("#{ s2 }")/)
    irb(main):026:1>   end
    => nil
    irb(main):027:0> td_match(doc, 'Description', 'QA Test Customer')
    => true
    

    稍微清理一下:

    def td_match(doc, s1, s2)
      !!doc.at(
        %Q/td[class="label"]:contains("#{ s1 }") + td[class="data"] div:contains("#{ s2 }")/
      )
    end
    

    或者,将其添加到 Nokogiri::HTML::Document:

    class Nokogiri::HTML::Document
      def td_match(s1, s2)
        !!self.at(
          %Q/td[class="label"]:contains("#{ s1 }") + td[class="data"] div:contains("#{ s2 }")/
        )
      end
    end
    
    doc.td_match('Description', 'QA Test Customer')
    => true
    

    【讨论】:

    • 干得好铁皮人。我在另一个项目中使用 Nokogiri 进行了一些屏幕截图并考虑过。鉴于你给我扔了一个垒球,我完全同意这样做!
    • 在你的第一个简单示例中得到了 doc.at('td.label + td.data').text 并且我得到了 nil:NilClass (NoMethodError )”。看起来很奇怪,因为我们正在传递 HTML,所以我们知道 doc 不是 nil...
    • 这不是doc 是nil,而是访问器没有找到这些类彼此相邻的标签。结果,Nokogiri 返回nil,而nil.text 不是定义的方法。也许示例 HTML 不是对真实 HTML 的准确描述?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多