2011-01-06 11 views
12

साथ पार्स एचटीएमएल मैं निम्न HTMLएचटीएमएल चपलता पैक और Linq

(..) 
<tbody> 
<tr> 
    <td class="name"> Test1 </td> 
    <td class="data"> Data </td> 
    <td class="data2"> Data 2 </td> 
</tr> 
<tr> 
    <td class="name"> Test2 </td> 
    <td class="data"> Data2 </td> 
    <td class="data2"> Data 2 </td> 
</tr> 
</tbody> 
(..) 

जानकारी मेरे पास है नाम => तो "Test1" & "Test2" है। मैं क्या जानना चाहता हूं कि मैं अपने नाम के आधार पर "डेटा" और "डेटा 2" में मौजूद डेटा कैसे प्राप्त कर सकता हूं।

वर्तमान में मैं उपयोग कर रहा हूँ:

var data = 
    from 
     tr in doc.DocumentNode.Descendants("tr") 
    from 
     td in tr.ChildNodes.Where(x => x.Attributes["class"].Value == "name") 
    where 
     td.InnerText == "Test1" 
    select tr; 

लेकिन मैं {"Object reference not set to an instance of an object."} मिलता है जब मैं में data

+0

बिल्कुल, आप क्या करने की कोशिश कर रहे हैं? और वह कोड क्या है जिसे आप नहीं चाहते हैं? –

+0

हे, क्षमा करें, मैं इसे जोड़ना भूल गया हूं, मैं इसे अब जोड़ रहा हूं –

+0

क्या आप हमें बता सकते हैं कि आपकी त्रुटि क्या है? या आप क्या होने की उम्मीद कर रहे हैं जो ऐसा नहीं होता है? –

उत्तर

13

अपने प्रयास के लिए के रूप में, आप अपने कोड के साथ दो मुद्दे हैं:

  1. ChildNodes अजीब है - यह भी खाली स्थान के पाठ नोड्स, जो नहीं है एक class गुण (गुण नहीं कर सकते हैं देता है, की पाठ्यक्रम)।
  2. जेम्स वाल्फोर्ड ने टिप्पणी की, पाठ के चारों ओर की जगहें महत्वपूर्ण हैं, शायद आप उन्हें ट्रिम करना चाहते हैं।
इन दो सुधार, निम्न कार्य करता साथ

:

var data = 
     from tr in doc.DocumentNode.Descendants("tr") 
     from td in tr.Descendants("td").Where(x => x.Attributes["class"].Value == "name") 
    where td.InnerText.Trim() == "Test1" 
    select tr; 
1

यहाँ एक तरीका है देखने के लिए प्रयास करें - पहले एक डेटा संरचना में सभी डेटा पार्स, और फिर इसे पढ़ें। मैं एक शब्दकोश है, जहां <td> के वर्ग एक कुंजी है और पाठ एक मूल्य है के लिए हर <tr> बारी

HtmlWeb hw = new HtmlWeb(); 
HtmlDocument doc = hw.Load("http://jsbin.com/ezuge4"); 
HtmlNodeCollection nodes = doc.DocumentNode 
           .SelectNodes("//table[@id='MyTable']//tr"); 
var data = nodes.Select(
    node => node.Descendants("td") 
     .ToDictionary(descendant => descendant.Attributes["class"].Value, 
         descendant => descendant.InnerText.Trim()) 
     ).ToDictionary(dict => dict["name"]); 
string test1Data = data["Test1"]["data"]; 

यहाँ: यह थोड़ा जटिल होता है और निश्चित रूप से अधिक मान्यता जरूरत है, लेकिन यहाँ जाता है। इसके बाद, मैं शब्दकोशों की सूची को शब्दकोशों के शब्दकोश (टिप - अमूर्त दूर) में बदल देता हूं, जहां प्रत्येक <tr> की name कुंजी है।

0

td.InnerText == "Test1" 

के बजाय

कोशिश

td.InnerText == " Test1 " 

या

d.InnerText.Trim() == "Test1" 
4

यहाँ XPATH तरीका है - हममम ... हर कोई इन दिनों बिजली XPATH के बारे में भूल गया और सी # XLinq, पर विशेष रूप से ध्यान केंद्रित करने की है, :-)

यह फ़ंक्शन नाम के साथ जुड़े सभी डेटा मान हो जाता है लगता है:

public static IEnumerable<string> GetData(HtmlDocument document, string name) 
{ 
    return from HtmlNode node in 
     document.DocumentNode.SelectNodes("//td[@class='name' and contains(text(), '" + name + "')]/following-sibling::td") 
     select node.InnerText.Trim(); 
} 

उदाहरण के लिए, इस कोड को सभी 'Test2' डेटा डंप हो जाएगा:

HtmlDocument doc = new HtmlDocument(); 
    doc.Load(yourHtml); 

    foreach (string data in GetData(doc, "Test2")) 
    { 
     Console.WriteLine(data); 
    } 
+0

मैंने 'x' के साथ एक xpath के बारे में सोचा, लेकिन इसमें एक बड़ी समस्या है: 'टेस्ट 1' की खोज में 'टेस्ट 10', 'नोटटेस्ट 1' और बहुत कुछ भी मिलेगा। मुझे वास्तव में उस समस्या को पाने के लिए पर्याप्त xpath नहीं पता है ... – Kobi

+0

@ कोबी - यदि आप शामिल नहीं करना चाहते हैं, तो आप = का उपयोग कर सकते हैं। यदि व्हाइटस्पेस एक समस्या है, तो उन्हें सामान्यीकृत स्थान के साथ हटाया जा सकता है, अन्यथा इस लिंक में अधिक जानकारी है: http://stackoverflow.com/questions/1852571/xpath-function-to-remove-white-space –

+2

कारण I XPath पर लिंक जवाब पसंद करते हैं क्योंकि बाद में पढ़ने और समझना मुश्किल होता है। पूर्व पूरी तरह से स्पष्ट है कि क्या इरादा है, और यदि आवश्यक हो तो आप क्वेरी को डिबग करने के लिए सबक्वायरीज़ में तोड़ सकते हैं। XPath डीबग करने के लिए उलझन और असंभव है। यह जांचना मुश्किल है कि यह बहुत सारे परीक्षण डेटा के बिना सही काम कर रहा है। XPath वाक्यविन्यास पर एक आधिकारिक पृष्ठ के लिए बस googling घृणास्पद कोर है। मुझे अभी भी एचएपी पसंद है, लेकिन हर बार जब मैं एक XPath कथन देखता हूं तो मैं क्रिंग करता हूं। –

-1

मैं सिफारिश कर सकते हैं दो तरीकों में से एक:

http://htmlagilitypack.codeplex.com/, जो एचटीएमएल को वैध एक्सएमएल में परिवर्तित करता है जिसे ओओटीबी लिंक के साथ पूछताछ की जा सकती है।

या,

Linq एचटीएमएल (http://www.superstarcoders.com/linq-to-html.aspx) है, जो है, जबकि (कि एक संकेत, कीथ था) CodePlex पर नहीं रखा करने के लिए, सुविधाओं से फ़ौजों की चौकी के का एक उचित वर्किंग सेट देता है।

संबंधित मुद्दे