XPath来获取两个元素之间的兄弟姐妹

时间:2015-05-21 17:52:31

标签: ruby xpath nokogiri mechanize

使用以下标记我需要获得中间的

<tr class="H03">
  <td>Artist</td>
  ...
<tr class="row_alternate">
  <td>LIMP</td>
  <td>Orion</td>
  ...
</tr>
<tr class="row_normal">
  <td>SND</td>
  <td>Tender Love</td>
  ...
</tr>
<tr class="report_total">
  <td>&nbsp;</td>
  <td>&nbsp;</td>
  ...
</tr>

这是<tr class="H03"><tr class="report_total">之间的每个兄弟姐妹。我正在使用机械化和nokogiri,所以仅限于他们的xpath支持。查看各种StackOverflow问题后,我最好的尝试是

page.search('/*/tr[@class="H03"]/following-sibling::tr[count(. | /*/tr[@class="report_total"]/preceding-sibling::tr)=count(/*/tr[@class="report_total"]/preceding-sibling::tr)]')

返回一个空数组,并且非常复杂,以至于我的有限xpath fu完全不知所措!。

2 个答案:

答案 0 :(得分:1)

Mechanize在这里有一些辅助方法可供使用。

假设您正在执行以下操作:

require 'mechanize'
agent = Mechanize.new
page = agent.get('http://www.website.com')
start_tr = page.at('.H03')

此时,tr将是您在问题中列出的第一个tr的nokogiri xml元素。

然后你可以用:

遍历兄弟姐妹
next_tr = start_tr.next_sibling

执行此操作直到您按下要停止的tr。

trs = Array.new

until next_tr.attributes['class'].name == 'report_total'
    next_tr = next_tr.next_sibling
    trs << next_tr
end

如果您希望范围包含start和stop trs(H03和report_total),只需调整上面的代码即可将它们包含在trs数组中。

答案 1 :(得分:1)

您可以尝试以下xpath:

//tr[@class='H03']/following-sibling::tr[following-sibling::tr[@class='report_total']]

在xpath之上选择<tr>之后的所有tr[@class='H03'],其中<tr>具有以下兄弟tr[@class='report_total']或换句话说选定的<tr>位于tr[@class='report_total']之前}。