Пропустить итерацию нескольких элементов или как удалить

Есть такая таблица (пример, в реале количество столбцов может быть разным):

<table class="table table-bordered table-condensed">
<tbody>
    <tr>
        <td colspan="2">1</td>
        <td>Название</td>
        <td class="text-blue">Название</td>
        <td>1</td>
        <td class="">Тест</td>
    </tr>
    <tr>
        <td colspan="2">2</td>
        <td>Название2</td>
        <td class="text-blue">Название2</td>
        <td>2</td>
        <td class="">Тест2</td>
    </tr>
    <tr>
        <td colspan="6" class="uc-discip-group text-center">НАЗВАНИЕ</td>
    </tr>
    <tr><td rowspan="3">1</td><td>55</td><td>Программное обеспечение</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr><td>55</td><td>Экономике</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr><td>55</td><td>Технологии</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr>
</tbody>
</table>

Я использую HtmlAgilityPack для разбора html-элементов.

Написал такой код:

var nodes = page.DocumentNode.SelectNodes("//table[@class='table table-bordered table-condensed']/tbody");

foreach (var table in nodes)
{
    foreach (var row in table.SelectNodes("tr"))
    {
        foreach (var cell in row.SelectNodes("td"))
        {
            // какое-то действие..
        }
    }
}

Но у меня, ни в какую не получается исключить данный код:

<tr>
    <td colspan="6" class="uc-discip-group text-center">НАЗВАНИЕ</td>
</tr>
<tr><td rowspan="3">1</td><td>55</td><td>Программное обеспечение</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr><td>55</td><td>Экономике</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr><td>55</td><td>Технологии</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr>

Можно, конечно, заморочиться с регулярными выражениями, но мне кажется, можно и без них обойтись.

Может быть можно, как-то узнать, позицию последних элементов tr и использовать LINQ?

Я попробовал использовать Skip, но в него нужно передать номер элемента, а выяснить не удалось.

UPD:

В этой строке:

<tr><td rowspan="3">1</td><td>55</td><td>Программное обеспечение</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr><td>55</td><td>Экономике</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr><td>55</td><td>Технологии</td><td class="text-blue">Тест</td><td>1</td><td class=""></td></tr>

Неизвестно сколько может быть tr, поэтому, варианты как с Skip/Take не подходят.


Ответы (1 шт):

Автор решения: Andrei Khotko

Вам нужно всего лишь изменить селектор. Селектор будет выглядеть следующим образом:

var xPathSelector = @"//table[@class='table table-bordered table-condensed']/tbody/tr/td[text()='НАЗВАНИЕ']/parent::tr/preceding::tr"
var nodes = page.DocumentNode.SelectNodes(xPathSelector);

Он найдет вам все элементы tr до элемента td с текстом "НАЗВАНИЕ". Краткое пояснение:

  • td[text()='НАЗВАНИЕ'] - находим элемент td, текст которого равен НАЗВАНИЕ.
  • parent::tr - находим ближайший тег-родитель tr для тега td
  • preceding::tr - находим все теги tr на одном и том же уровне, которые предшествуют текущему тегу tr

Проверять написанные вами XPath-селекторы можно с помощью браузера Mozila Firefox (если есть в Google Chrome - напишите в комментарии об этом, пожалуйста). Перейдя на нужную страницу, нажимаете F12 и во вкладке Инспектор в строке поиска вводите XPath селектор

→ Ссылка