Html Agility Pack-Problem z wyborem podnodu

Chcę wyeksportować mój plan działania Asics do iCal, a ponieważ Asics nie oferuje tej usługi, postanowiłem zbudować mały skrobak na własny użytek. To, co chcę zrobić, to wziąć wszystkie zaplanowane biegi z mojego planu i wygenerować kanał iCal na podstawie tego. Używam C# i Html Agility Pack.

To, co chcę zrobić, to iterację wszystkich zaplanowanych uruchomień (są to węzły div). Następnie chcę wybrać kilka różnych węzłów z moimi węzłami run. Mój kod wygląda jak to:

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 />";
}

Mój problem polega na tym, że run.SelectSingleNode("//div[@class='date']").InnerText nie wybiera węzła z podaną ścieżką XPath w obrębie danego węzła run. Wybiera pierwszy węzeł, który pasuje do ścieżki XPath w całym dokumencie.

Jak mogę wybrać pojedynczy węzeł z podaną ścieżką XPath w bieżącym węźle?

Dziękuję.

Update

Próbowałem zaktualizować mój łańcuch XPath do tego:

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

To powinno wybrać <div class="date"></div> element w bieżącym węźle, prawda? Próbowałem tego. ale mam ten błąd:

Wyrażenie musi oceniać na node-set. Opis: bezwypadkowy wyjątek wystąpił podczas wykonanie bieżącego żądania internetowego. Proszę przejrzeć ślad stosu, aby uzyskać więcej informacji informacje o błędzie i gdzie pochodzi z Kodeksu.

Szczegóły Wyjątku: System.Xml.XPath.XPathException: Expression must evaluate to a node-set.

Jakieś sugestie?
Author: tereško, 2011-05-30

2 answers

Kilka rzeczy, które pomogą Ci w pracy z wyrażeniami HtmlAgilityPack i XPath .

Jeśli run jest HtmlNode, to:

  1. run.SelectNodes("//div[@class='date']")
    Will będzie zachowywał się dokładnie tak jak doc.DocumentNode.SelectNodes("//div[@class='date']")

  2. run.SelectNodes("./div[@class='date']")
    da Ci wszystkie <div> węzły, które są dziećmi run węzła. Nie będzie szukał głębiej, tylko na następnym poziomie głębokości.

  3. run.SelectNodes(".//div[@class='date']")
    zwróci wszystkie <div> węzły z tym atrybutem klasy, ale nie tylko obok run węzła, ale także będzie szukał w głębi (każdy możliwy jego potomek)

Będziesz musiał wybrać pomiędzy 2. lub 3., w zależności od tego, który zaspokoi Twoje potrzeby:)

 60
Author: Oscar Mederos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-04 12:59:58

W XPATH, // oznacza wszystkie dzieci i wnuki poniżej bieżącego węzła. Musisz więc wymyślić bardziej restrykcyjne wyrażenie XPATH. Jeśli podasz prawdziwy HTML i to, czego dokładnie szukasz, możemy pomóc Ci kopać dalej.

O błędzie jaki masz:

.div[@class='date'] jest nieprawidłowa, ponieważ {[2] } jest przyklejona do div. Możesz użyć div[@class='date'], lub ./div[@class='date'], które moim zdaniem są równoważne. To dlatego, że . jest XPath axe, który jest aliasem dla self i oznacza "aktualny węzeł".

 3
Author: Simon Mourier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-31 07:56:19