从我的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>
答案 0 :(得分: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)
代替。即使它只能在你的电脑上工作 - 我也无从知晓 - 它仍然是一个好习惯。