2014-01-21 83 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