Html Agility Pack - проблема выбора поднода

asp.net-mvc c# html-agility-pack

Вопрос

Я хочу экспортировать план 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: выражение должно оцениваться в наборе узлов.

Какие-либо предложения?

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

Несколько вещей, которые помогут вам при работе с выражениями 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., в зависимости от того, какой из них удовлетворяет ваши потребности :)


Популярные ответы

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

Об ошибке вы имеете:

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



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему