2014-01-21 110 views
1

從我的xml testreport我需要做一個加權總和的缺陷,組合每個項目和所有日期的總和。最後,我需要一些列表,我可以在網站上以圖表形式顯示。我堅持最後一點來提取列表。總結和分組值

我附上了迄今爲止我所得到的xml和codesnip。

namespace LinqTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int WDCFact_1 = 5; 
      int WDCFact_2 = 10; 
      int WDCFact_3 = 20; 

      XDocument test = XDocument.Load(@"..\..\Helpers\XMLFile1.xml"); 
      var selected = from p in test.Descendants("Sample") 
          group p by p.Element("Date").Value into gDate 
          from projects in 
           (from proj in gDate 
           group proj by proj.Element("Project").Value) 
          select new 
          { 
           Date = DateTime.Parse(gDate.Key), 
           proj = projects.Key, 
           WDC = projects.Sum(t => (t.Element("Severity3") == null || t.Element("Severity3").Value == "") ? 0 : (int)t.Element("Severity3") * WDCFact_3) + 
            projects.Sum(t => (t.Element("Severity1") == null || t.Element("Severity1").Value == "") ? 0 : (int)t.Element("Severity1") * WDCFact_1) + 
            projects.Sum(t => (t.Element("Severity2") == null || t.Element("Severity2").Value == "") ? 0 : (int)t.Element("Severity2") * WDCFact_2) 
          }; 

      var allprj = (from p in selected 
         select p.proj).Distinct().ToList(); 

      var prj = from p in selected.GroupBy(d => d.Date) 
         select new 
         { 
          _d = p.LastOrDefault() 
         }; 

      string mybreakpoint = ""; 
     } 
    } 
} 

預期結果:

List<DateTime> Dates = {12-02-2014, 13-02-2014, 14-02-2014, 15-02-2014} 
List<int> WDC_prj1 = {45, 150, 65, 85} 
List<int> WDC_prj2 = {110, 110, 115, 260} 
List<int> WDC_prj3 = {250, 0, 235, 245} 
List<int> WDC_prj4 = {170, 60, 250, 240} 
List<int> WDC_prj5 = {0, 205, 0, 15} 

XML輸入:

<HistoricalData xmlns:xsi="http:www.w3.org/2001/XMLSchema-instance"> 
    <Sample> 
     <Date>12-02-2013 00:00</Date>  
     <Project>Prj1</Project> 
     <Business_Line>BL1</Business_Line>  
     <Severity1>9</Severity1> 
    </Sample> 
    <Sample> 
     <Date>12-02-2013 00:00</Date>  
     <Project>Prj2</Project> 
     <Business_Line>BL1</Business_Line>  
     <Severity1>8</Severity1>  
     <Severity2>1</Severity2>  
     <Severity3>3</Severity3> 
    </Sample> 
    <Sample> 
     <Date>12-02-2013 00:00</Date>  
     <Project>Prj3</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>8</Severity1>  
     <Severity2>3</Severity2>  
     <Severity3>9</Severity3> 
    </Sample> 
    <Sample> 
     <Date>12-02-2013 00:00</Date>  
     <Project>Prj4</Project>  
     <Business_Line>BL2</Business_Line>  
     <Severity1>2</Severity1>  
     <Severity2>0</Severity2>  
     <Severity3>8</Severity3> 
    </Sample> 
    <Sample> 
     <Date>13-02-2013 00:00</Date>  
     <Project>Prj1</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>6</Severity1>  
     <Severity2>8</Severity2>  
     <Severity3>2</Severity3> 
    </Sample> 
    <Sample> 
     <Date>13-02-2013 00:00</Date>  
     <Project>Prj2</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>8</Severity1>  
     <Severity2>3</Severity2>  
     <Severity3>2</Severity3> 
    </Sample> 
    <Sample> 
     <Date>13-02-2013 00:00</Date>  
     <Project>Prj3</Project>  
     <Business_Line>BL1</Business_Line> 
    </Sample> 
    <Sample> 
     <Date>13-02-2013 00:00</Date>  
     <Project>Prj4</Project>  
     <Business_Line>BL2</Business_Line>  
     <Severity1>0</Severity1>  
     <Severity2>6</Severity2>  
     <Severity3>0</Severity3> 
    </Sample> 
    <Sample> 
     <Date>13-02-2013 00:00</Date>  
     <Project>Prj5</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>1</Severity1>  
     <Severity2>6</Severity2>  
     <Severity3>7</Severity3> 
    </Sample> 
    <Sample> 
     <Date>14-02-2013 00:00</Date>  
     <Project>Prj1</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>3</Severity1>  
     <Severity2>1</Severity2>  
     <Severity3>2</Severity3> 
    </Sample> 
    <Sample> 
     <Date>14-02-2013 00:00</Date>  
     <Project>Prj2</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>7</Severity1>  
     <Severity2>0</Severity2>  
     <Severity3>4</Severity3> 
    </Sample> 
    <Sample> 
     <Date>14-02-2013 00:00</Date>  
     <Project>Prj3</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>7</Severity1>  
     <Severity2>4</Severity2>  
     <Severity3>8</Severity3> 
    </Sample> 
    <Sample> 
     <Date>14-02-2013 00:00</Date>  
     <Project>Prj4</Project>  
     <Business_Line>BL2</Business_Line>  
     <Severity1>8</Severity1>  
     <Severity2>5</Severity2>  
     <Severity3>8</Severity3> 
    </Sample> 
    <Sample> 
     <Date>15-02-2013 00:00</Date>  
     <Project>Prj1</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>1</Severity1>  
     <Severity2>4</Severity2>  
     <Severity3>2</Severity3> 
    </Sample> 
    <Sample> 
     <Date>15-02-2013 00:00</Date>  
     <Project>Prj2</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>8</Severity1>  
     <Severity2>6</Severity2>  
     <Severity3>8</Severity3> 
    </Sample> 
    <Sample> 
     <Date>15-02-2013 00:00</Date>  
     <Project>Prj3</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>1</Severity1>  
     <Severity2>8</Severity2>  
     <Severity3>8</Severity3> 
    </Sample> 
    <Sample> 
     <Date>15-02-2013 00:00</Date>  
     <Project>Prj4</Project>  
     <Business_Line>BL2</Business_Line>  
     <Severity1>8</Severity1>  
     <Severity2>8</Severity2>  
     <Severity3>6</Severity3> 
    </Sample> 
    <Sample> 
     <Date>15-02-2013 00:00</Date>  
     <Project>Prj5</Project>  
     <Business_Line>BL1</Business_Line>  
     <Severity1>3</Severity1>  
     <Severity2>0</Severity2>  
     <Severity3>0</Severity3> 
    </Sample> 
</HistoricalData> 

回答

2

這會做的伎倆:

List<DateTime> Dates = selected.Select(each => each.Date).Distinct().ToList(); 
List<int> WDC_prj1 = selected 
    .Where(sample => sample.proj == "Prj1") 
    .Select(sample => sample.WDC).ToList(); 
List<int> WDC_prj2 = selected 
    .Where(sample => sample.proj == "Prj2") 
    .Select(sample => sample.WDC).ToList(); 
// etc. 

請注意,2014年的日期(您給出的預期結果)實際上並不存在於您的示例中(2013年的全部內容),但我認爲這是一個錯字,您只需要一個不同日期的列表。

編輯:

好吧,我剛剛注意到,如果PrjX值被跳過,你想有一個0來代替。

我的代碼會給你WDC_prj5 = {205, 15},而你實際上需要{0, 205, 0, 15}(因爲在前四個樣本之後沒有Prj5)。

我們可以通過迭代循環中的示例並跟蹤哪些Prjs丟失來滿足此要求。然後 - 每當我們再次遇到Prj1 - 我們用零代替它們。

例如:

var values = Enumerable.Range(1, 5).ToDictionary(n => n, n => new List<int>()); 
bool firstIteration = true; 
var visited = new BitArray(5, false); 
foreach(var sample in selected) 
{ 
    int number = Int32.Parse(sample.proj.Last().ToString()); 
    visited[number - 1] = true; 
    if (number == 1 && !firstIteration) 
    { 
     for (int i = 0; i < 5; i++) 
     { 
      if (!visited[i]) 
       values[i + 1].Add(0); 
     } 
     visited.SetAll(false); 
    } 
    values[number].Add(sample.WDC); 
    firstIteration = false; 
} 

現在只是:

List<int> WDC_prj1 = values[1]; 
List<int> WDC_prj2 = values[2]; 

等等

或者,如果你認爲LINQ是冷靜和性能方面的考慮不嚇唬你,你可以把BitArray帶走:

foreach(var sample in selected) 
{ 
    int number = Int32.Parse(sample.proj.Last().ToString()); 
    if (number == 1) 
    { 
     // we just started a new cycle... 
     int expectedNumberOfValues = values.Values.Max(list => list.Count); 
     values = values.ToDictionary(
      kvp => kvp.Key, 
      kvp => kvp.Value.Concat(Enumerable.Repeat(0, expectedNumberOfValues - kvp.Value.Count)).ToList()); 
    } 
    values[number].Add(sample.WDC); 
} 

收集的結果仍然是相同的:

List<int> WDC_prj1 = values[1]; 
List<int> WDC_prj2 = values[2]; 

PS。

請注意,請注意DateTime.Parse

這是文化敏感,它可以崩潰在另一個版本的Windows上。

例如在我的電腦上它試圖解析13-02-2013 00:00(並且它在12月2日錯誤地解析了12-02-2013)。

在這種情況下,您最好使用DateTime.ParseExact(d, "dd-MM-yyyy HH:mm", CultureInfo.InvariantCulture)代替。即使它只能在你的電腦上工作 - 我無法知道 - 這仍然是一個好習慣。

+0

它的魔力:-)採取DateTime.Parse的評論。只是想知道如何將日期提取到類似的列表中。 – ThomasB

+0

@ThomasB我的代碼爲您提供了與您所期望的輸出(2013/2014混淆除外)相同的確切日期列表。因此,如果結果不符合您的期望,我需要知道以什麼方式 –

+0

現在我明白了 - 工作得很好:-) – ThomasB