XML 节点最新时间戳 C#
XML node Latest timestamp C#
我只需要打印同一个员工一次并检查它是否是最新的时间戳。我只需要一次员工 ID,但需要它的最新时间戳。
这是我目前的结果,使用不同的时间戳打印相同的 ID(示例):
1 2015-03-16T21:32:30
1 2015-03-16T21:33:30
2 2015-03-16T21:32:30
3 2015-03-16T21:32:30
2 2015-03-16T21:33:30
这就是我的代码现在的样子。
static void Main(string[] args)
{
XElement xelement = XElement.Load("data.xml");
IEnumerable<XElement> employees = xelement.Elements();
Console.WriteLine("List of Employee and latest timestamp:");
foreach (var employee in employees)
{
Console.WriteLine("{0} has Employee ID {1}",
employee.Element("Employee").Value,
employee.Element("ChangeTimeStamp").Value);
}
Console.ReadKey();
}
明确地说,我希望我的结果是:
1 2015-03-16T21:33:30
2 2015-03-16T21:33:30
3 2015-03-16T21:32:30
您需要按 Employee
元素的值对员工节点进行分组,如下所示:
XElement xelement = XElement.Load("data.xml");
var employees = xelement.Elements()
.Select(e => new
{
Name = e.Element("Employee").Value,
ChangeTimestamp = DateTime.Parse(e.Element("ChangeTimestamp").Value)
})
.GroupBy(e => e.Name)
.Select( g => new
{
Name = g.Key,
ChangeTimestamp = g.Max(e => e.ChangeTimestamp)
});
现在,当你迭代时,你应该有正确的值
foreach(var employee in employees)
{
Console.WriteLine("{0} {1}", employee.Name, employee.ChangeTimestamp);
}
编辑我
要删除除最新版本之外的其他元素,您应该过滤它们并从其父项中删除每个元素。代码应如下所示:
XElement xelement = XElement.Load("data.xml");
xelement.Elements()
.GroupBy(e => e.Element("Employee").Value)
.SelectMany(g =>
{
var maxDate = g.Max( e => DateTime.Parse(e.Element("ChangeTimestamp").Value));
return g.Where(e => DateTime.Parse(e.Element("ChangeTimestamp").Value) != maxDate);
})
.ToList()
.ForEach(e=>e.Remove());
这当然不是最佳解决方案,但它为您指明了正确的方向。调整它以满足您的需要。
编辑二
粘贴箱中的文件有 3 个不同的员工,而不是一个员工有 3 个不同的 ChangeTimestamp
。我尝试了以下代码片段并且有效:
XDocument doc = XDocument.Load(@"path");
doc.Root.Elements("Employee")
.GroupBy(e => e.Element("Employee").Value)
.SelectMany(g=>
{
return g.OrderByDescending(e => DateTime.Parse(e.Element("ChangeTimeStamp").Value))
.Skip(1);
})
.ToList()
.ForEach(e=>e.Remove());
您可以将您的数据放在 Dictionary<int, DateTime>
中,因为您只想为每个员工输入一个条目。
Dictionary<int, DateTime> employeeList = new Dictionary<int, DateTime>();
foreach (var employee in employees)
{
int employeeId = employee.Element("Employee").Value;
DateTime employeeDate;
bool dateOk = DateTime.TryParse(employee.Element("ChangeTimeStamp").Value, employeeDate);
if (dateOk)
{
if (employeeList.ContainsKey(employeeId))
{
if (employeeList[employeeId].Value.CompareTo(employeeDate) < 0)
{
employeeList[employeeId].Value = employeeDate;
}
}
else
{
employeeList.Add(employeeId, employeeDate);
}
}
}
在那之后,每个员工都有一个最新日期的条目。
我只需要打印同一个员工一次并检查它是否是最新的时间戳。我只需要一次员工 ID,但需要它的最新时间戳。
这是我目前的结果,使用不同的时间戳打印相同的 ID(示例):
1 2015-03-16T21:32:30
1 2015-03-16T21:33:30
2 2015-03-16T21:32:30
3 2015-03-16T21:32:30
2 2015-03-16T21:33:30
这就是我的代码现在的样子。
static void Main(string[] args)
{
XElement xelement = XElement.Load("data.xml");
IEnumerable<XElement> employees = xelement.Elements();
Console.WriteLine("List of Employee and latest timestamp:");
foreach (var employee in employees)
{
Console.WriteLine("{0} has Employee ID {1}",
employee.Element("Employee").Value,
employee.Element("ChangeTimeStamp").Value);
}
Console.ReadKey();
}
明确地说,我希望我的结果是:
1 2015-03-16T21:33:30
2 2015-03-16T21:33:30
3 2015-03-16T21:32:30
您需要按 Employee
元素的值对员工节点进行分组,如下所示:
XElement xelement = XElement.Load("data.xml");
var employees = xelement.Elements()
.Select(e => new
{
Name = e.Element("Employee").Value,
ChangeTimestamp = DateTime.Parse(e.Element("ChangeTimestamp").Value)
})
.GroupBy(e => e.Name)
.Select( g => new
{
Name = g.Key,
ChangeTimestamp = g.Max(e => e.ChangeTimestamp)
});
现在,当你迭代时,你应该有正确的值
foreach(var employee in employees)
{
Console.WriteLine("{0} {1}", employee.Name, employee.ChangeTimestamp);
}
编辑我
要删除除最新版本之外的其他元素,您应该过滤它们并从其父项中删除每个元素。代码应如下所示:
XElement xelement = XElement.Load("data.xml");
xelement.Elements()
.GroupBy(e => e.Element("Employee").Value)
.SelectMany(g =>
{
var maxDate = g.Max( e => DateTime.Parse(e.Element("ChangeTimestamp").Value));
return g.Where(e => DateTime.Parse(e.Element("ChangeTimestamp").Value) != maxDate);
})
.ToList()
.ForEach(e=>e.Remove());
这当然不是最佳解决方案,但它为您指明了正确的方向。调整它以满足您的需要。
编辑二
粘贴箱中的文件有 3 个不同的员工,而不是一个员工有 3 个不同的 ChangeTimestamp
。我尝试了以下代码片段并且有效:
XDocument doc = XDocument.Load(@"path");
doc.Root.Elements("Employee")
.GroupBy(e => e.Element("Employee").Value)
.SelectMany(g=>
{
return g.OrderByDescending(e => DateTime.Parse(e.Element("ChangeTimeStamp").Value))
.Skip(1);
})
.ToList()
.ForEach(e=>e.Remove());
您可以将您的数据放在 Dictionary<int, DateTime>
中,因为您只想为每个员工输入一个条目。
Dictionary<int, DateTime> employeeList = new Dictionary<int, DateTime>();
foreach (var employee in employees)
{
int employeeId = employee.Element("Employee").Value;
DateTime employeeDate;
bool dateOk = DateTime.TryParse(employee.Element("ChangeTimeStamp").Value, employeeDate);
if (dateOk)
{
if (employeeList.ContainsKey(employeeId))
{
if (employeeList[employeeId].Value.CompareTo(employeeDate) < 0)
{
employeeList[employeeId].Value = employeeDate;
}
}
else
{
employeeList.Add(employeeId, employeeDate);
}
}
}
在那之后,每个员工都有一个最新日期的条目。