2011-12-13 11 views
9

Jak bym skutecznie analizować href wartość atrybutu z tego:HTML Agility paczka: parsowanie tag href

<tr> 
<td rowspan="1" colspan="1">7</td> 
<td rowspan="1" colspan="1"> 
<a class="undMe" href="/ice/player.htm?id=8475179" rel="skaterLinkData" shape="rect">D. Kulikov</a> 
</td> 
<td rowspan="1" colspan="1">D</td> 
<td rowspan="1" colspan="1">0</td> 
<td rowspan="1" colspan="1">0</td> 
<td rowspan="1" colspan="1">0</td> 
[...] 

jestem zainteresowany posiadaniem id gracza, który jest: Oto kod I do tej pory:

 // Iterate all rows (players) 
     for (int i = 1; i < rows.Count; ++i) 
     { 
      HtmlNodeCollection cols = rows[i].SelectNodes(".//td"); 

      // new player 
      Dim_Player player = new Dim_Player(); 

       // Iterate all columns in this row 
       for (int j = 1; j < 6; ++j) 
       { 
        switch (j) { 
         case 1: player.Name = cols[j].InnerText; 
           player.Player_id = Int32.Parse(/* this is where I want to parse the href value */); 
           break; 
         case 2: player.Position = cols[j].InnerText; break; 
         case 3: stats.Goals = Int32.Parse(cols[j].InnerText); break; 
         case 4: stats.Assists = Int32.Parse(cols[j].InnerText); break; 
         case 5: stats.Points = Int32.Parse(cols[j].InnerText); break; 
        } 
       } 
+0

Jeśli ciężko kodowane indeksy w 'switch', dlaczego należy użyć' for' pętla? Dlaczego nie 'player.Position = cols [2] .InnerText;' –

+0

Dobra rada. Przywracam stary kod, który napisałem, więc nie pomyślałam o tym. –

Odpowiedz

20

Bazując na przykład ten pracował dla mnie:

HtmlDocument htmlDoc = new HtmlDocument(); 
htmlDoc.Load("test.html"); 
var link = htmlDoc.DocumentNode 
        .Descendants("a") 
        .First(x => x.Attributes["class"] != null 
          && x.Attributes["class"].Value == "undMe"); 

string hrefValue = link.Attributes["href"].Value; 
long playerId = Convert.ToInt64(hrefValue.Split('=')[1]); 

Dla rzeczywistego użytkowania trzeba dodać sprawdzanie błędów itp

+0

Działa również dla mnie! Czy to tylko ja, czy to raczej niewygodne, ponieważ musimy użyć 'htmlDoc', w którym znajdziemy wszystkie węzły z klasą 'undMe', podczas gdy zamiast tego możemy użyć' cols [j] ', które mają' href' w jego InnerHtml? –

+0

Tworzysz bardzo mocne założenie dotyczące lokalizacji twojego łącza - może to działać dobrze, ale jest bardzo sztywne i ulegnie zerwaniu, tj. Jeśli dodasz kolejną kolumnę. Przedstawione podejście nie byłoby, ponieważ * zapytanie * o link na minimalnych założeniach – BrokenGlass

+0

W rzeczywistości, jedynym problemem z tym jest "First()", który jest statyczny i zawsze przynosi pierwszy znaleziony element. Potrzebuję czegoś dynamicznego, które pozwoli uzyskać rzeczywisty element. –

2

pomocą wyrażenia XPath go znaleźć:

foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@class='undMe']")) 
{ 
     HtmlAttribute att = link.Attributes["href"]; 
     Console.WriteLine(new Regex(@"(?<=[\?&]id=)\d+(?=\&|\#|$)").Match(att.Value).Value); 
}