Получите конкретные таблицы с пакетом гибкости Html

c# html-agility-pack xpath

Вопрос

У меня возникли проблемы с получением определенной таблицы с помощью HTML Agility Pack. Я тоже не могу изменить фактический HTML, поэтому я не могу использовать другие идентификаторы или классы или что-то еще.

Может ли кто-нибудь показать мне, как я могу получить доступ к каждой отдельной таблице из следующего?

<table class="newTable">
      //table 1 contents
    <table border="0" cellpadding="3" cellspacing="2" width="100%">
         //table 1 - A contents
    </table>
</table>
<table border="0" cellpadding="0" cellspacing="0" class="newTable">
     //table 2 contents
    <table width="100%" border="0" cellspacing="2" cellpadding="0">
        //table 2 - A contents
    </table>
    <table width="100%" border="0" cellspacing="2" cellpadding="0">
       //table 2 - B contents
    </table>
    <table width="100%" cellspacing="2" cellpadding="0">
       //table 2 - C contents
    </table>
</table>
<table>
     //table 3 contents
</table>

Прямо сейчас, если я позвоню

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table");
foreach (var cell in table.SelectNodes("//tr/td"))
{
     string someVariable = cell.InnerText
}

Я бы прошел через все. Я хочу иметь доступ к таблицам по-разному, чтобы соотнести, где я храню данные.

Я пробовал смотреть на что-то вроде

doc.DocumentNode.SelectNodes("//table[1]");

но использование индекса, похоже, не работает, когда я пытаюсь указать таблицу с ним, он по-прежнему читается во всех таблицах или нет.

То же самое относится к этому, оно либо не работает вообще, либо получает все.

foreach (var cell in table.SelectNodes("//table").Skip(some_number))
{
     string someVariable = cell.InnerText
}

Я использую пакет NuGet пакета Agility Pack 1.4.9

РЕДАКТИРОВАТЬ:

Моя попытка получить ТОЛЬКО Таблица 1 - Содержание А. Оба они дают null или endcodingfound исключения.

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table/tr/td/table[1]");

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]/tr/td/table[1]");

Принятый ответ

Ошибка со вторым вызовом, «// tr / td» вернется к корневому элементу. Ваш индексщик является правильным решением для первой части вашей проблемы, второй может быть исправлен, указав, что вы хотите перемещаться с того места, где находитесь:

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]");
foreach (var cell in table.SelectNodes(".//tr/td")) // **notice the .**
{
     string someVariable = cell.InnerText
}

Не уверен, что еще происходит, но, расширяя тестовую таблицу до этого кода , следующее работает только в моем тесте. Это может означать, что вам нужно разделить немного больше контекста.

Это Документ, который я использовал для тестов:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <table class="newTable">
        <tr>
            <td>
                <table border="0" cellpadding="3" cellspacing="2" width="100%">
                    <tr><td>
                        //table 1 - A contents
                    </td></tr>
                </table>
            </td>
        </tr>

    </table>
    <table border="0" cellpadding="0" cellspacing="0" class="newTable">
        <tr>
            <td>
                //table 2 contents
                <table width="100%" border="0" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - A contents
                        </td>
                    </tr>
                </table>
                <table width="100%" border="0" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - B contents
                        </td>
                    </tr>
                </table>
                <table width="100%" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - C contents
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
    <table>
        <tr>
            <td>
                //table 3 contents
            </td>
        </tr>
    </table>
</body>
</html>

И этот код для извлечения значений, которые вы используете:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(text);

var node1A = doc.DocumentNode.SelectSingleNode("//table[1]//table[1]");
string content1A = node1A.InnerText;
Console.WriteLine(content1A);

var node2C = doc.DocumentNode.SelectSingleNode("//table[2]//table[3]");
string content2C = node2C.InnerText;
Console.WriteLine(content2C);

Показывает:

введите описание изображения здесь

Обновить

Хорошо, я взял ваш фактический HTML, и я также получил NullReference. Должно быть, что-то очень смущает Пакет Agility Pack, не знаю почему. Некоторые эксперименты с API Linq, похоже, работают, но я надеюсь, что это может быть альтернативой для вас:

var table = doc.DocumentNode.DescendantsAndSelf("table").Skip(1).First().Descendants("table").First();
var tds   = table.Descendants("td");


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow