Html Agility Pack - проблема выбора подузла - PullRequest
27 голосов

Я хочу экспортировать свой рабочий план Asics в iCal, и поскольку Asics не предлагает эту услугу, я решил создать небольшой скребок для личного пользования.Я хочу взять все запланированные запуски из моего плана и сгенерировать канал iCal на его основе.Я использую C # и Html Agility Pack.

Что я хочу сделать, так это перебрать все мои запланированные запуски (они являются узлами div).Затем я хочу выбрать несколько разных узлов с моими узлами выполнения.Мой код выглядит так:

foreach (var run in doc.DocumentNode.SelectSingleNode("//div[@id='scheduleTable']").SelectNodes("//div[@class='pTdBox']"))
{
    number++;
    string date = run.SelectSingleNode("//div[@class='date']").InnerText;
    string type = run.SelectSingleNode("//span[@class='menu']").InnerHtml;
    string distance = run.SelectSingleNode("//span[@class='distance']").InnerHtml;
    string description = run.SelectSingleNode("//div[@class='description']").InnerHtml;
    ViewData["result"] += "Dato: " + date + "<br />";
    ViewData["result"] += "Tyep: " + type + "<br />";
    ViewData["result"] += "Distance: " + distance + "<br />";
    ViewData["result"] += "Description: " + description + "<br />";
    ViewData["result"] += run.InnerHtml.Replace("<", "&lt;").Replace(">", "&gt;") + "<br />" + "<br />" + "<br />";
}

Моя проблема в том, что run.SelectSingleNode("//div[@class='date']").InnerText не выбирает узел с данным XPath в данном узле выполнения.Он выбирает первый узел, соответствующий XPath во всем документе.

Как выбрать один узел с данным XPath в текущем узле?

Спасибо.

Обновление

Я попытался обновить строку XPath до следующего:

string date = run.SelectSingleNode(".div[@class='date']").InnerText;

Это должно выбрать элемент <div class="date"></div> в текущем узле, верно?Ну, я попробовал это, но получил эту ошибку:

Выражение должно вычисляться как набор узлов.Описание: во время выполнения текущего веб-запроса произошло необработанное исключение.Просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.Xml.XPath.XPathException: выражение должно оцениваться как набор узлов.

Есть предложения?

Ответы [ 2 ]

58 голосов
/ 31 мая 2011

Несколько вещей, которые помогут вам при работе с HtmlAgilityPack и XPath выражениями.

Если run является HtmlNode, то:

  1. run.SelectNodes("//div[@class='date']")
    Воля будет вести себя точно так же, как doc.DocumentNode.SelectNodes("//div[@class='date']")

  2. run.SelectNodes("./div[@class='date']")
    Даст вам все <div>узлы, которые являются потомками узла run.Он не будет искать глубже, только на следующем уровне глубины.

  3. run.SelectNodes(".//div[@class='date']")
    Вернет все узлы <div> с этим атрибутом класса, но не только на следующемк узлу run, но также будет искать в глубине (каждый возможный потомок)

Вам придется выбирать между 2. или 3., в зависимости от того, какой из них удовлетворяет вашемунеобходимо:)

3 голосов
/ 31 мая 2011

В XPATH // означает всех детей и внуков ниже текущего узла. Поэтому вам нужно придумать более ограничительное выражение XPATH. Если вы предоставите настоящий HTML-код и именно то, что ищете, мы поможем вам продолжить поиск.

Об ошибке у вас есть:

.div[@class='date'] недопустимо, потому что . привязано к div. Вы можете использовать div[@class='date'] или ./div[@class='date'], которые я считаю эквивалентными. Это потому, что . - это XPATH ax , который является псевдонимом для self и означает «текущий узел».

...