2013-02-21 13 views
28

आशा है कि कोई मेरी मदद कर सकता है।एचटीएमएलएजिलिटीपैक और नोड्स और सबनोड्स का चयन

चलो कहते हैं कि मैं एक HTML दस्तावेज़ है कि इस उदाहरण की तरह कई divs शामिल है:

<div class="search_hit"> 

    <span prop="name">Richard Winchester</span> 
    <span prop="company">Kodak</span> 
    <span prop="street">Arlington Road 1</span> 

</div> 
<div class="search_hit"> 

    <span prop="name">Ted Mosby</span> 
    <span prop="company">HP</span> 
    <span prop="street">Arlington Road 2</span> 

</div> 

मैं HtmlAgilityPack का उपयोग कर HTML दस्तावेज़ प्राप्त करने के लिए। मुझे यह जानने की ज़रूरत है कि मैं प्रत्येक "search_hit" -div के लिए स्पैन कैसे प्राप्त कर सकता हूं?

foreach (HtmlAgilityPack.HtmlNode node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) 
{ 
    foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("//span[@prop]")) 
    { 

    } 
} 

प्रत्येक div गुण के रूप में शामिल फैला के साथ एक वस्तु होना चाहिए:

मेरी पहली सोचा कुछ इस तरह था। आई ई।

public class Record 
    { 
     public string Name { get; set; } 
     public string company { get; set; } 
     public string street { get; set; } 
    } 

और यह सूची तो भरा जाएगा:

public List<Record> Results = new List<Record>(); 

लेकिन XPath का उपयोग कर मैं उपनोड यह करना चाहिए के रूप में में एक खोज नहीं कर रहा है। यह seams है कि यह पूरे दस्तावेज़ को बार-बार खोजता है।

मेरा मतलब है कि मुझे पहले से ही इस तरह से काम मिल रहा है कि मुझे बस पूरे पृष्ठ की अवधि मिलती है। लेकिन तब मुझे स्पैन और divs के बीच कोई संबंध नहीं है। मतलब: मैं अब और नहीं जानता कि कौन सा काल संबंधित div से संबंधित है।

क्या कोई समाधान ढूंढता है? मैंने पहले से ही इतना खेला है कि मैं अब पूरी तरह उलझन में हूं :)

किसी भी मदद की सराहना की जाती है!

+0

अपना कोड पार्सिंग (पूर्ण कार्य समाधान) को पार्स करने के तरीकों के लिए मेरा उत्तर देखें। –

उत्तर

24

मेरे लिए निम्नलिखित काम करता है। महत्वपूर्ण बात यह है कि बेनीबेला ने दूसरे कॉल में 'सिलेक्ट नोड्स' में एक डॉट जोड़ने का उल्लेख किया था।

List<Record> lstRecords=new List<Record>(); 
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) 
{ 
    Record record=new Record(); 
    foreach (HtmlNode node2 in node.SelectNodes(".//span[@prop]")) 
    { 
    string attributeValue = node2.GetAttributeValue("prop", ""); 
    if (attributeValue == "name") 
    { 
     record.Name = node2.InnerText; 
    } 
    else if (attributeValue == "company") 
    { 
     record.company = node2.InnerText; 
    } 
    else if (attributeValue == "street") 
    { 
     record.street = node2.InnerText; 
    } 
    } 
    lstRecords.Add(record); 
} 
42

यदि आप // का उपयोग करते हैं, तो यह दस्तावेज़ से शुरू होता है।

उपयोग .// वर्तमान नोड

foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes(".//span[@prop]")) 

से सभी खोज या सिर्फ प्रत्यक्ष बच्चों के लिए खोज करने के लिए पूरी तरह से उपसर्ग ड्रॉप करने:

foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("span[@prop]")) 
+0

यदि मैं ऐसा करता हूं: foreach (HtmlAgilityPack.HtmlNode node2 नोड में। चयन नोड्स ("span [@prop]")) विजुअल स्टूडियो एक त्रुटि के साथ आ रहा है। –

+0

किस तरह की त्रुटि? आप इसके लिए '। /' उपसर्ग भी आज़मा सकते हैं। (मैं वास्तव में अनुमान लगा रहा हूं) – BeniBela

+0

मैंने दोनों की कोशिश की और दोनों समाप्त हो रहे हैं: NullReferenceException: ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट के उदाहरण पर सेट नहीं है। –

2

सबसे पहले, इस पर एक नज़र डालें: Html Agility Pack - Problem selecting subnode

यहाँ अपने प्रश्न के लिए एक पूर्ण काम कर समाधान है:

IList<Record> results = new List<Record>(); 
foreach (var node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) { 
    var record = new Record(); 
    record.Name = node.SelectSingleNode(".//span[@prop='name']").InnerText; 
    record.company = node.SelectSingleNode(".//span[@prop='company']").InnerText; 
    record.street = node.SelectSingleNode(".//span[@prop='street']").InnerText; 
    results.Add(record); 
} 

आप सवाल मैं करने के लिए आप इशारा पढ़ें , आप देखेंगे कि ./span[@prop='name'] बिल्कुल वैसा ही है, क्योंकि span नोड div नोड के बच्चे (प्रत्यक्ष) बच्चे हैं।


span नोड्स उन prop गुण नहीं है, तो, और आप उन्हें आदेश वे दिखाई देते हैं पर निर्भर करता है प्रदान करना चाहते हैं, तो आप कर सकते हैं:

foreach (var node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) { 
    var spanNodes = node.SelectNodes("./span"); 
    var record = new Record(); 
    record.Name = spanNodes[0].InnerText; 
    record.company = spanNodes[1].InnerText; 
    record.street = spanNodes[2].InnerText; 
    results.Add(record); 
} 
2

शर्म की बात है मुझ पर :)

आप सभी सही थे।

मुझे समस्या मिली। यह NullReferenceException मुझे परेशान रखता है इसलिए मैंने इसे विस्तार से देखने के लिए और अधिक समय बिताया। उन सभी divs के बीच में एक ही "वर्ग = 'खोज-हिट' विशेषता के साथ एक div था लेकिन बिना स्पैन के। यह दूसरी लूप पर एक त्रुटि के माध्यम से क्यों है।

foreach (HtmlAgilityPack.HtmlNode node in doc.DocumentNode.SelectNodes("//span[@prop]/ancestor::div[@class='search_hit']")) 
    { 
     Record rec = new Record(); 
     foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes(".//span[@prop]")) 
      { 
      } 
      rList.Results.Add(rec); 
    } 

उपरोक्त कोड काम कर रहा है।

आपके समय और मदद के लिए धन्यवाद दोस्तों!

0

मैंने इसका इस्तेमाल किया। वर्ग कन्वर्ट आईडी

HtmlNodeCollection nodes = dokuman.DocumentNode.SelectNodes("//div[@id='search_hit']//span[@prop]"); 


      for (int i = 0; i < nodes .Count; i++) 
     { 
      var record = new Record(); 


       record.Name = links[i].InnerText; results.Add(record); } 
संबंधित मुद्दे