2016-12-11 52 views
2

我有一個列表包含10個不同記錄的行。我在C#控制檯應用程序中循環這個列表,並將值插入到另一個列表中,但它只選取第一條記錄並將其插入新列表中10次。C#奇怪的問題 - 無法賦值從右到左變量

當我調試時,唯一值顯示在循環中,但它們沒有被分配給左變量。

List<Job> jobList=new List<Job>(); 
foreach (var row in rows) 
{ 
    Job job = new Job(); 
    job.Title = row.SelectSingleNode("//h2[@class='jobtitle']").ChildNodes[1].Attributes["title"].Value; 
    job.summary = row.SelectSingleNode("//span[@class='summary']").InnerText 
    jobList.add(job); 
} 

任何想法,發生了什麼?

我也用垃圾收集器,但依然沒有起色:

job = null; 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

下面是@Andrew建議後更新的代碼,但沒有奏效。右側保存更新的值,但它們沒有被分配給左側變量。

foreach (var row in rows) 
{ 
    try 
    { 
     var job = new Job(); 
     var title = row.SelectSingleNode("//h2[@class='jobtitle']").ChildNodes[1].Attributes["title"].Value; 
     var company = row.SelectSingleNode("//span[@class='company']").InnerText.Replace("\n", "").Replace("\r", ""); 
     var location = row.SelectSingleNode("//span[@class='location']").InnerText.Replace("\n", "").Replace("\r", ""); 
     var summary = row.SelectSingleNode("//span[@class='summary']").InnerText.Replace("\n", "").Replace("\r", ""); 

     job.Title = title; 
     job.Company = company; 
     job.Location = location; 
     job.Summary = summary; 
     jobList.Add(job); 

     job = null; 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     counter++; 
     Status("Page# " + pageNumber.ToString() + " : Record# " + counter + " extracted"); 
    } 
    catch (Exception) 
    { 
     AppendRecords(jobList); 
     jobList.Clear(); 
    } 
    //save file 
} 
+2

問題在於如何從XML檢索值 - 你總是檢索相同的值 – Fabio

+0

@Fabio - OP想要從每一行檢索相同的值,並且代碼(乍一看)看起來應該是這樣做的。 – ChrisF

+0

@Fabio我正在使用HtmlAgilityPack來檢索值和該部分工作正常,因爲我已經確保在調試過程中。問題是價值沒有被分配到右側。 這裏有截圖,你可以看到自己 [試玩截圖](http://screencast.com/t/ZZliIrkXktqq) – Hamad

回答

3

嗨你不告訴我們什麼rows變量涉及到,但我認爲這些都是在一個單一的XmlDocument節點。您用於從這些節點提取值的XPath表達式不正確,因爲它們將始終導航到文檔中的同一節點,而不管當前的節點是row

這裏的演示該問題一個簡單的例子: -

static void Main(string[] args) 
{ 
    XmlDocument x = new XmlDocument(); 
    x.LoadXml(@"<rows> <row><bla><h2>bob1</h2></bla></row> <row><bla><h2>bob2</h2></bla></row> </rows>"); 
    var rows = x.GetElementsByTagName("row"); 
    foreach (XmlNode row in rows) 
    { 
     var h2 = row.SelectSingleNode("//h2").ChildNodes[0].Value; 
     Console.WriteLine(h2); 
    } 
} 

從這個輸出將是

bob1 
bob1 

不是你期待什麼呢?用Dot Net Fiddle中的示例玩一玩。再看看你的XPath表達式。您當前的表達式//h2說「不管當前節點如何,給我所有h2元素」。而.//h2會爲您提供h2元素,它們是當前row節點的後代,這可能是您需要的。

+0

你是對的,但我已經收集了多行記錄,使用這個LOC HtmlDocument document = web。負載(URL); var rows = document.DocumentNode.SelectNodes(「// td [@ id ='resultsCol'] // div [@ class ='row result']」)。ToList(); 所以在循環行中包含唯一的10條記錄(作業) – Hamad

+0

好的,但每個'行'仍然屬於同一個父文檔,因此'SelectSingleNode(// h2)'方法回到該文檔的根目錄並且然後選擇所有'h2'元素。嘗試添加「。」到你的XPath的開始,並告訴我們是否解決了這個問題。 – Rob

+0

這裏是工作代碼(與提到的問題)。 https://github.com/hamad1472/helpme/blob/master/Scraper/Program.cs – Hamad