Использование HTMLAgilityPack для получения всех значений выбранного элемента

Вот что у меня есть до сих пор:

            HtmlAgilityPack.HtmlDocument ht = new HtmlAgilityPack.HtmlDocument();


       TextReader reader = File.OpenText(@"C:\Users\TheGateKeeper\Desktop\New folder\html.txt");
        ht.Load(reader);

        reader.Close();

        HtmlNode select= ht.GetElementbyId("cats[]");


        List<HtmlNode> options = new List<HtmlNode>();

        foreach (HtmlNode option in select.ChildNodes)
        {
            if (option.Name == "option")
            {
                options.Add(option);
            }
        }

Теперь у меня есть список всех «параметров» для элемента select. К каким свойствам мне нужно получить доступ, чтобы получить ключ и текст?

Итак, если, например, html для одного варианта будет:

<option class="level-1" value="1">Funky Town</option>

Я хочу получить на выходе:

1 - Funky Town

Спасибо

Редактировать: я только что кое-что заметил. Когда я получил дочерние элементы элементов «Выбрать», он вернул элементы типа «опция» и элементы типа «#текст».

Хммм... #text содержит строку, которую я хочу, но select имеет значение.

Я думал, что HTMLAgilityPack — это парсер html? Почему это дало мне такие запутанные значения?


person TheGateKeeper    schedule 08.03.2012    source источник
comment
Вы можете опубликовать часть html из исходного файла?   -  person lincolnk    schedule 08.03.2012


Ответы (2)


Это связано с конфигурацией по умолчанию для синтаксического анализатора html; он настроил <option> как HtmlElementFlag.Empty (с комментарием «иногда они содержат, а иногда нет...»). Тег <form> имеет ту же настройку (CanOverlap + Empty), из-за которой они отображаются как пустые узлы в dom без каких-либо дочерних узлов.

Вам нужно удалить этот флаг перед синтаксическим анализом документа.

HtmlNode.ElementsFlags.Remove("option");

Обратите внимание, что свойство ElementsFlags является статическим, и любые изменения повлияют на весь дальнейший анализ.

person sisve    schedule 08.03.2012

edit: вам, вероятно, следует выбирать узлы option напрямую через xpath. Я думаю, что это должно работать для этого:

var options = select.SelectNodes("option");

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

foreach (var option in options)
{
    int value = int.Parse(option.Attributes["value"].Value);
    string text = option.InnerText;

}


вы можете добавить некоторую проверку работоспособности атрибута, чтобы убедиться, что он существует.

person lincolnk    schedule 08.03.2012
comment
Я тоже так думал, но внутренний текст для каждого элемента равен . - person TheGateKeeper; 08.03.2012
comment
хм, я использую InnerText, и это работает для меня. Возможно, посмотрите на option.FirstChild и посмотрите, существует ли он/содержит ли ваше значение. - person lincolnk; 08.03.2012