2012-05-14 16 views
15

Neden belgemdeki tüm <li> öğeleri seçiyor? Benim istediğimHtml Agility Pack, Düğümden bir düğüm seç

HtmlWeb web = new HtmlWeb(); 
HtmlDocument doc = web.Load(url); 

var travelList = new List<Page>(); 
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']") 
        .SelectNodes("//li"); 

"myTrips" bir id ile <div> tüm <li> unsurları elde etmektir.

cevap

15

Eğer ("// li") Başka bir SelectNodes yapmak ancak, eğer id "myTrips" ile sadece div üzerinde selectNodes yapacağını bekliyor çünkü o üstten başka bir arama performn edecek Biraz kafa karıştırıcı Belgenin

Bildirimi biriyle birleştirerek bunu çözdüm, ancak bu yalnızca "mytrips" kimliğine sahip yalnızca bir div'in bulunduğu bir web sayfasında çalışır. Sorgu şu şekilde görünecektir:

doc.DocumentNode.SelectNodes ("// div [@ id = 'myTrips'] // li");

Bir Linq sorgusu ile bunu yapabilirsiniz
4

:

HtmlWeb web = new HtmlWeb(); 
HtmlDocument doc = web.Load(url); 

var travelList = new List<HtmlNode>(); 
foreach (var matchingDiv in doc.DocumentNode.DescendantNodes().Where(n=>n.Name == "div" && n.Id == "myTrips")) 
{ 
    travelList.AddRange(matchingDiv.DescendantNodes().Where(n=> n.Name == "li")); 
} 

Ben

1

yardımcı olur diye düşündüm belirli bir düğümde bir selectNodes yöntemi çalıştırılırsa, bu, lutfen bana karşı sezgisel görünüyor umut Genelde belgede değil, yalnızca o düğümün altındaki maddeleri arar.

Bu satırı değiştirirseniz, her neyse OP: var liOfTravels = doc.DocumentNode.SelectSingleNode ("// div [@ id = 'myTrips']") SelectNodes ("// li");

TO: var liOfTravels = doc.DocumentNode.SelectSingleNode ("// div [@ id = 'myTrips']") SelectNodes ("li");

Bence iyi olacaksınız, sadece aynı sorunu yaşadım ve bu benim için düzeltildi. Eğer li, sahip olduğunuz düğümün doğrudan bir çocuğunun olması gerektiğinden emin değilim.

12

İkinci satırdaki noktayı not edin. Temelde tamamen XPath sözdizimi dayanır HTMLAgitilityPack bu konuda, ancak sonuç bu sorgular etkin bir aynı olduğu için, sigara sezgisel: yeni bir düğüm oluşturma

doc.DocumentNode.SelectNodes("//li"); 
some_deeper_node.SelectNodes("//li"); 
+0

Sorguların aynı olduğunu sanmıyorum. Aslında ilk seçimi yaptığında "// div [@ id = 'myTrips']" geçerli düğüm değişir. Bu yüzden ikinci seçim ".//li" (mevcut düğümden herhangi bir yerde) ve "// li" (kökten herhangi bir yerde) olmamalıdır. Çeviklik tam olarak ne yapılması bekleniyor. – derloopkat

+0

@derloopkat, onlar ** aynıdır (burada IMHO yoktur, eğer olmasaydı, eğer çözüm noktasında noktayı düşüremezdiniz, ama yapamazsınız, değil mi?). Ne yazık ki, hangi düğümde olursanız olun, HTMLAgilityPack kökten arama yapar. IMHO kısmı budur - genellikle verilen düğüm üzerinde odaklanma noktası, ** 'den, bu köprüyü yeniden başlatmaya devam etmenizdir. İkinci alt sorguda nokta eklemeden çözüm sorusu hiç mantıklı gelmeyecek, bu yüzden onları destekleme neden soru? – greenoldman

+0

Farklı şeyler hakkında konuşuyoruz. Sorguların aynı olmadığını söylediğimde "// li" ve ".//li" hakkında konuşuyordum. "Bu sorgular" ile, aşağıdaki sorgulara başvurursunuz. – derloopkat

5

bazı durumlarda yararlı olabilir ve etmenizi sağlar XPath'leri kullanmak daha sezgisel. Bunu birkaç yerde faydalı buldum.

var myTripsDiv = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']"); 
var myTripsNode = HtmlNode.CreateNode(myTripsDiv.InnerHtml); 
var liOfTravels = myTripsNode.SelectNodes("//li");