#html-agility-pack
#html-agility-pack
Вопрос:
Я использую HtmlAgilityPack для получения следующего HTML (обратите внимание на вложенную таблицу):
<table class="123">
<tr>
<table class="789">
<tr>
<td>abc</td>
</tr>
<tr>
<td>def</td>
</tr>
</table>
</tr>
<tr>
<td>info 1</td>
</tr>
<tr>
<td>info 2</td>
</tr>
<tr>
<td>info 3</td>
</tr>
</table>
Теперь я пытаюсь найти умный способ получить некоторую информацию из родительской таблицы и некоторую информацию из вложенной таблицы…
Пока у меня есть следующее:
var parentTable = document.DocumentNode.SelectNodes("//table[@class='123']").FirstOrDefault();
var nestedTable = parentTable.SelectNodes("//table[@class='789']").FirstOrDefault();
Теперь я могу поиграть с вложенной таблицей и получить то, что я хочу (abc, def)…
Но когда я пытаюсь получить <tr>
из родительской таблицы вот так:
var parentTableRows = parentTable.SelectNodes(".//tr");
Похоже, что он также включает (в коллекцию) <tr>
’ы из вложенной таблицы…
Другими словами, согласно приведенному выше HTML-коду, я ожидал получить коллекцию из 4 <tr>
файлов, но поскольку она включает <tr>
файлы из вложенной таблицы, я получаю коллекцию из 6 <tr>
файлов.
Как я могу пропустить первую <tr>
, которая содержит вложенную таблицу, чтобы я мог поиграть и получить нужную мне информацию (info1, info2, info3) (надеюсь, я имею смысл …)
Заранее спасибо!
Ответ №1:
//
это выражение XPATH, которое означает «сканировать все узлы и вложенные узлы». Вот почему //tr
получает все tr ниже корневой.
Если вы просто сделаете это parentTable.SelectNodes("tr")
(или "./tr"
что эквивалентно), вы выберете все TR ниже корневой.
Если вы хотите пропустить первую, вы можете добавить фильтр XPATH для элемента position()
(функция XPATH):
var parentTableRows = parentTable.SelectNodes("tr[position() > 1]");