2011-07-29 29 views
1

我想在DataGridView中顯示三列。 這裏是我的XML的一個樣本:試圖用Linq查詢並在DataGridView中顯示

<root> 
<string id = "STRING_ID"> 
    <node1> Some data </node1> 
    <node2> 
     <type>data</type> 
    </node2> 
    <Translations> 
     <language name="ARABIC"> 
      <value>Some data</value> 
      <date_last_changed>7-4-2011</date_last_changed> 
     </language> 
     <language name="CHINESE"> 
     ... 
     ... 
    </Translations> 
</string> 

<string id = "..."> 
    ... 
    ... 

我想顯示的第一列是字符串ID,屬性值。 我想要顯示的第二列是每個string<value>數據,其中<language name>等於ENGLISH_US。 我想要顯示的第三列是每個string<value>數據,其中<language name>等於組合框中當前選定的項目(填充了每種語言的名稱)。

這是目前我的Linq查詢:

var query_Id = from va in xdoc.Descendants("language") 
         where va.Attribute("name").Value == ("ENGLISH_US") 
        select new 
        { 
         StringID = va.Parent.Parent.Attribute("id").Value, 
         English = va.Element("value").Value, 
         Custom = <incomplete> 
        }; 

這樣做的問題是,雖然這給了我前兩列,我不能想辦法拿到第三。實質上,我正在尋找一種解決方案,看起來像幾個選擇基於像WHERE language name = "VALUE"等東西。簡單一點。

回答

2

這應該工作。 (您可能想在SingleOrDefault上添加一些錯誤檢查)

var query = from va in xdoc.Descendants("language") 
       select new 
       { 
       StringID = va.Parent.Parent.Attribute("id").Value, 
       Language = va.Attribute("name").Value, 
       LanguageData = va.Element("value").Value, 
       }; 

    var query2 = from x in query 
       group x by x.StringID into xg 
       select new 
       { 
       StringID = xg.Key, 
       English = xg.SingleOrDefault(x => x.Language == "ARABIC").LanguageData, 
       Custom = xg.SingleOrDefault(x => x.Language == otherLanguage).LanguageData, 
       }; 
+0

令人驚歎。它確實有效。感謝您的回覆,我不知道該怎麼做。我最終試圖在這個空指針異常之前使用'.Where()'子句。謝謝! –

1

既然你想每個字符串的項目列表保持在Linq的外部序列,然後從那裏工作。您可以使用嵌套查詢來拾取特定項目中的值。

例如,如果您確定每個語言ID只有一個,那麼您可以使用類似這樣的內容,但如果語言ID在特定字符串中使用了兩次,它將會失敗。

string customLangId = ... 
    var results = from s in doc.Descendants("string") 
        let vs = s.Descendants("language") 
         .ToDictionary(l => (string)l.Attribute("name"), l => (string)l.Element("value")) 
        select new 
          { 
           StringID = (string)s.Attribute("id"), 
           English = vs.ContainsKey("ENGLISH_US") ? vs["ENGLISH_US"] : "(No Translation)", 
           Custom = vs.ContainsKey(customLangId) ? vs[customLangId] : "" 
          }; 

另一種選擇是對兩個內部查詢使用let。一個用於英語,另一個用於自定義語言。您可以使用FirstOrDefault結束這些操作,它會默默地忽略任何重複的ID,但會以掃描語言值列表兩次爲代價。您還可以創建ToDictionary的自定義替換以提供您正在查找的確切語義(即先保留,後保留或拋出自定義異常)。

+0

嗨!感謝您的回覆。我用過你的代碼,但是如何在DataGridView中顯示?我試圖使用'dataGridView1.DataSource = results.ToList()',但DataGridView在我運行該程序時顯示爲空白。 –

+0

謝謝你的回覆,我解決了這個問題。 –

+0

另外,在我進行'let'內部查詢之前,我知道我越來越近了。我對這些東西仍然很陌生。我感謝您的幫助! –