2010-12-07 105 views
1

我有以下XML,並且我需要一個查詢,以便在通過特定統計信息時提取Year和Return_Value。如何在linq xml語句中使用where子句

當前的代碼不起作用,因爲在字典對象的一個​​添加語句中不能有兩個where子句。有針對這個的解決方法嗎?

foreach (var row in rows) 
{ 
    myHoldingsDistribution.Add(row.Descendants() 
     .Where(y => y.Name.LocalName == keyName) 
     .Select(q => q.Value).Max(), 
     Double.Parse(row.Descendants().Where(y => y.Name.LocalName == valueName) 
          .Select(q => q.Value).Max()) * multiplier); 

<Table> 
    <Year>1</Year> 
    <Statistic>0 Percentile</Statistic> 
    <Return_Value>0.0535644000000</Return_Value> 
</Table> 
    base {System.Xml.Linq.XContainer}: <Table> 
    <ALMRunResults_Year>1</ALMRunResults_Year> 
    <Statistic>0 Percentile</Statistic> 
    <Return_Value>0.0535644000000</Return_Value> 
</Table> 

FirstAttribute: null 
    HasAttributes: false 
    HasElements: true 
    IsEmpty: false 
    LastAttribute: null 
    Name: {Table} 
    NodeType: Element 
    Value: "10 Percentile0.0535644000000" 

編輯

在下面的語句 - 我想最好要。凡兩次過濾掉那些沒有1個百分。

myHoldingsDistribution.Add(row.Descendants() 
     .Where(y => y.Name.LocalName == keyName) 
     .Select(q => q.Value).Max(), 
     Double.Parse(row.Descendants().Where(y => y.Name.LocalName == valueName) 
          .Select(q => q.Value).Max()) * multiplier); 
+0

你是什麼意思「你不能有兩個where子句?你從你提供的代碼中得到什麼錯誤? – StriplingWarrior 2010-12-07 17:19:08

+0

「我想最好要。凡兩次過濾掉那些沒有1個百分。」 - 什麼阻止你?你通常可以只連鎖。凡陳述在一起:`rows.Where(...),其中(...)`什麼,當你試試這個,什麼做的代碼看起來像發生? – StriplingWarrior 2010-12-07 17:53:05

回答

2

我真的非常貴LINQ查詢糊塗了,好像你在第一段中描述的行爲並沒有真正反映你的代碼試圖做的事。我相信你和你的代碼所遇到的問題更多的是比什麼都重要的Double.Parse方法的位置,因爲下面的代碼編譯和運行得很好:

var myHoldingsDistribution = new Dictionary<object, object>(); 
var rows = new[] {new {Descendants = new[]{new {Name = new {LocalName = "test"}, Value = 0.05}}}}; 
var keyName = "test"; 
var valueName = "test"; 
var multiplier = 2d; 
foreach (var row in rows) 
{ 
    myHoldingsDistribution.Add(row.Descendants 
     .Where(y => y.Name.LocalName == keyName) 
     .Select(q => q.Value).Max(), 
     row.Descendants.Where(y => y.Name.LocalName == valueName) 
         .Select(q => q.Value).Max() * multiplier); 

} 

編輯

我還是很困惑這個問題。到目前爲止,你已經給了以下要求:

  1. 有2個,其中在LINQ XML語句條款
  2. 有兩個where子句中的一個附加聲明的字典對象
  3. SELECT * FROM我的數據集
  4. 篩選出那些不是1百分比

我會忽略前兩個因爲我不認爲他們是必要的。第三個要求比較簡單,假設你的數據格式有些固定。 (難道你真的是有一個「年」標籤和一個「ALMRunResults_Year」標籤?)

// Move the data into an object that can easily be manipulated. 
var transform = from r in rows 
       select new 
       { 
        key = r.Element(keyName).Value, 
        value = Double.Parse(r.Element(valueName).Value), 
        statistic = r.Element(statisticName).Value 
       }; 

一旦你選擇了值超出這個樣子,你可以使用LINQ到對象來執行你的過濾器描述和創建結果集合字典通過調用ToDictionary

var myHoldingsDistribution = transform 
    // Filter out anybody that's not 1 percentile 
    .Where(r => r.statistic == statisticFilter) 
    // Create a dictionary out of the keys and values 
    .ToDictionary(r => r.key, r => r.value); 

兩個代碼塊,我給你編譯和運行就好給出以下設置:

var text = 
@"<Root> 
    <Table> 
     <ALMRunResults_Year>1</ALMRunResults_Year> 
     <Statistic>0 Percentile</Statistic> 
     <Return_Value>0.0535644000000</Return_Value> 
    </Table> 
    <Table> 
     <ALMRunResults_Year>2</ALMRunResults_Year> 
     <Statistic>1 Percentile</Statistic> 
     <Return_Value>0.0535644000000</Return_Value> 
    </Table> 
</Root>"; 
var doc = XDocument.Parse(text); 
var rows = doc.Descendants("Table"); 

var keyName = "ALMRunResults_Year"; 
var valueName = "Return_Value"; 
var statisticName = "Statistic"; 
var statisticFilter = "1 Percentile"; 

這有道理嗎?

編輯2

WHERE統計僅= 「0個百分點, 25個百分點,50個百分點,75 百分」 等

所以,當你在談論2 where子句,你的意思是你想要「百分位數= 0或百分位數= 25」,例如?有幾種方法可以做到這一點。最簡單的方法可能是使用Contains方法:

var statisticFilters = new[]{ 
    "0 Percentile", "25 Percentile", "50 Percentile", "75 Percentile" 
}; 
... 
var myHoldingsDistribution = transform 
    .Where(r => statisticFilters.Contains(r.statistic)) 
    .ToDictionary(r => r.key, r => r.value);