HTMLAgilityPack – Трябва да зададете свойството UseIdAttribute на true, за да активирате тази функция

Опитвам се да използвам HTMLAgilityPack с VS2008/.Net 3.5. Получавам тази грешка, дори ако задам OptionUseIdAttribute на true, въпреки че трябва да е true по подразбиране.

Error Message:
 You need to set UseIdAttribute property to true to enable this feature

Stack Trace:
    at HtmlAgilityPack.HtmlDocument.GetElementbyId(String id)

Пробвах версия 1.4.6 и 1.4.0, нито една не работи.

Версия 1.4.6 - Net20/HtmlAgilityPack.dll

Версия 1.4.0 - Net20/HtmlAgilityPack.dll

Това е кодът,

    HtmlWeb web = new HtmlWeb();
    HtmlDocument doc = web.Load(url);
    HtmlNode table = doc.GetElementbyId("tblThreads");

Това също не проработи,

    HtmlWeb web = new HtmlWeb();
    HtmlDocument doc = new HtmlDocument { OptionUseIdAttribute = true };
    doc = web.Load(url);
    HtmlNode table = doc.GetElementbyId("tblThreads");

Как мога да поправя този проблем? Благодаря.


person user471317    schedule 18.10.2013    source източник
comment
Ако поставите точка на прекъсване след зареждане на вашия HtmlDocument, как изглежда документът. т.е. правилно ли се зарежда?   -  person Harrison    schedule 21.10.2013
comment
Да, изглежда добре след web.Load(url);   -  person user471317    schedule 21.10.2013
comment
Можете ли да посочите URL адреса?   -  person Harrison    schedule 23.10.2013
comment
Съжаляваме, това е личен url. Същият код работи добре на VS2010 с .Net 4.0. Но трябва да го накарам да работи на VS2008 проект.   -  person user471317    schedule 23.10.2013
comment
@user471317, тъй като отговорих на въпроса ви, ще ми дадете ли наградата?   -  person Ben Smith    schedule 28.10.2013
comment
„Приех“ вашия отговор. Предполагам, че точките не отиват автоматично към този плакат? Виждам, че вече имаш точките.   -  person user471317    schedule 30.10.2013


Отговори (1)


Първо използвах ILSpy на 1.4.0 HAP Dll. Отидох до класа HtmlDocument и видях, че методът GetElementById изглежда така:

// HtmlAgilityPack.HtmlDocument
/// <summary>
/// Gets the HTML node with the specified 'id' attribute value.
/// </summary>
/// <param name="id">The attribute id to match. May not be null.</param>
/// <returns>The HTML node with the matching id or null if not found.</returns>
public HtmlNode GetElementbyId(string id)
{
    if (id == null)
    {
        throw new ArgumentNullException("id");
    }
    if (this._nodesid == null)
    {
        throw new Exception(HtmlDocument.HtmlExceptionUseIdAttributeFalse);
    }
    return this._nodesid[id.ToLower()] as HtmlNode;
}

След това накарах ILSpy да анализира "_nodesid", защото във вашия случай по някаква причина той не е зададен. „HtmlDocument.DetectEncoding(TextReader)“ и „HtmlDocument.Load(TextReader)“ присвоява стойност на „_nodesid“.

Следователно можете да опитате алтернативен метод за четене на съдържанието от URL адреса, при което стойността "_nodesid" определено ще бъде присвоена, напр.

var doc = new HtmlDocument();
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
using (var response = (HttpWebResponse)request.GetResponse())
{
    using (var stream = response.GetResponseStream())
    {
        doc.Load(stream);
    }
}
var table = doc.GetElementbyId("tblThreads");

Този подход гарантира, че се извиква „HtmlDocument.Load(TextReader)“ и в този код виждам, че _nodesid определено ще бъде присвоен, така че този подход може (не съм компилирал кода, който предложих) работа.

person Ben Smith    schedule 23.10.2013
comment
Няма проблем. Радвам се, че мога да помогна. - person Ben Smith; 24.10.2013