我想將我的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("<", "<").Replace(">", ">") + "<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>
元素,對嗎?好吧,我試過這個,但得到了這個錯誤:
表達式必須評估為節點集。描述:執行當前Web請求期間發生未處理的異常。請查看堆棧跟踪以獲取有關錯誤及其源自代碼的位置的更多信息。
異常詳細信息:System.Xml.XPath.XPathException:Expression必須求值為節點集。
有什麼建議麼?
在使用HtmlAgilityPack和XPath表達式時,有些事情可以幫助您。
如果run
是HtmlNode
,那麼:
run.SelectNodes("//div[@class='date']")
將表現完全像doc.DocumentNode.SelectNodes("//div[@class='date']")
run.SelectNodes("./div[@class='date']")
將為您提供run
節點子節點的所有<div>
節點。它不會深入搜索,只能在下一個深度級別搜索。
run.SelectNodes(".//div[@class='date']")
將返回具有該類屬性的所有<div>
節點,但不僅會在run
節點旁邊,還會深入搜索(每個可能的後代)
您必須在2.或3.之間進行選擇,具體取決於哪一個滿足您的需求:)
在XPATH中, //
表示當前節點下的所有子節點和大子節點。所以你需要提出一個更嚴格的XPATH表達式。如果您提供真實的HTML,以及您正在尋找的內容,我們可以幫助您進一步挖掘。
關於您的錯誤:
.div[@class='date']
無效,因為.
堅持div
。您可以使用div[@class='date']
或./div[@class='date']
我相信它們是等效的。這是因為.
是一個XPATH ax ,它是self
的別名,意思是“當前節點”。