Найдите начало столбца с помощью xpath

#xpath #nokogiri

#xpath #nokogiri

Вопрос:

Допустим, HTML-таблица выглядит следующим образом:

 <tr> <td>     </td> <th> black </th> <th> white </th> </tr>
<tr> <th> 1st </th> <td> stuff </td> <td> stuff </td> </tr>
<tr> <th> 2nd </th> <td> earth </td> <td> stuff </td> </tr>
<tr> <th> 3rd </th> <td> stuff </td> <td> bingo </td> </tr>
  

Скажите также, что я нашел ячейку таблицы с надписью «bingo», используя XPath, возможно, с:

 @cell = @table.xpath('.//td[contains(text(), "bingo")]')
  

(Именно так вы бы сделали это с Nokogiri.)

Тогда каков канонический способ взять @cell и использовать его для поиска заголовка, который находится на вершине столбца, содержащего эту ячейку?

То есть, каков канонический способ превратить «бинго» в «белое», а «землю» в «черное»?

Комментарии:

1. Обратите внимание, что это было бы проще, а также семантически улучшило разметку, если бы вы использовали <thead> вокруг этой первой строки. (При условии, что у вас есть контроль над разметкой.)

Ответ №1:

Для нормализованной таблицы это относительное выражение XPath из любой td или th «ячейки»:

 preceding::*[
   self::td|self::th
][
   position() mod count(../*) = 0
][
   last()
]
  

Комментарии:

1. Я не понимаю, как position() mod count(../*) = 0 связано с поиском правильного столбца.

2. @LumpN: Для таблицы с R x C нормализацией расстояние между любой ячейкой и ее аналогами составляет C x N. C будет count(../ *), потому что это нормализованная таблица. position() это было бы расстояние по preceding оси . Вот и все.

3. Спасибо Алехандро. Что означает normalized?

4. @steven_noble: «Нормализовано» в том смысле, что нет ни colspan, ни rowspan.

5. @Alejandro: Для этого конкретного примера заключительное предложение — [last()] — не требуется. Мне интересно, есть ли у вас пример, показывающий, когда это будет необходимо?