Html Agility Pack - проблема выбора поднода
Я хочу экспортировать мой план Asics в iCal, и поскольку Asics не предлагает эту услугу, я решил создать небольшой скребок для моего личного использования. Я хочу сделать все запланированные прогонки из моего плана и создать на нем канал iCal. Я использую С# и 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("<", "<").Replace(">", ">") + "<br />" + "<br />" + "<br />";
}
Моя проблема заключается в том, что run.SelectSingleNode("//div[@class='date']").InnerText
не выбирает node с данным XPath в рамках данного пробега node. Он выбирает первый node, который соответствует XPath во всем документе.
Как я могу выбрать одиночный node с данным XPath в текущем node?
Спасибо.
Обновление
Я попробовал обновить мою строку XPath до этого:
string date = run.SelectSingleNode(".div[@class='date']").InnerText;
Это должно выбрать элемент <div class="date"></div>
в текущем node, правильно? Ну, я попробовал это, но получил эту ошибку:
Выражение должно оцениваться node -множество. Описание: необработанный исключение произошло во время выполнение текущего веб-запроса. Просмотрите трассировку стека информацию об ошибке и он возник из кода.
Сведения об исключении: System.Xml.XPath.XPathException: Выражение должно оцениваться node -множество.
Любые предложения?
Ответы
Ответ 1
Несколько вещей, которые помогут вам при работе с выражениями HtmlAgilityPack и XPath.
Если run
является HtmlNode
, то:
-
run.SelectNodes("//div[@class='date']")
Уилл будет вести себя точно так же, как doc.DocumentNode.SelectNodes("//div[@class='date']")
-
run.SelectNodes("./div[@class='date']")
Дадут вам все узлы <div>
, которые являются дочерними элементами run
node. Он не будет искать глубже, только на самом следующем уровне глубины.
-
run.SelectNodes(".//div[@class='date']")
Вернет все узлы <div>
с этим атрибутом класса, но не только рядом с run
node, но и будет искать по глубине (все возможные потомки)
Вам придется выбирать между 2. или 3., в зависимости от того, какой из них удовлетворяет ваши потребности:)
Ответ 2
В XPATH, //
означает всех детей и внуков ниже текущего node. Поэтому вам нужно придумать более ограничительное выражение XPATH. Если вы предоставляете реальный HTML-код и что именно ищете, мы можем помочь вам копать дальше.
Об ошибке, которая у вас есть:
.div[@class='date']
недействителен, поскольку .
привязан к div
. Вы можете использовать div[@class='date']
или ./div[@class='date']
, которые, я считаю, эквивалентны. Это связано с тем, что .
является XPATH ax, который является псевдонимом для self
и означает "текущий node".