2015-03-06 2 views
1

Мне нужно только один раз напечатать один и тот же сотрудник и проверить, установлена ​​ли его последняя временная метка. Мне нужен идентификатор сотрудника только один раз, но последняя временная метка.XML-узел. Последняя временная метка. C#

Это мой результат до сих пор, выводя тот же идентификатор с различными временными метками (пример):

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 
+1

Похоже, вы просто итерации через сотрудников. Вы пробовали что-нибудь для решения своей проблемы? Где вы испытываете проблемы? –

+0

Ну, я не знаю, как я могу сравнить временные метки друг с другом? – Girre

+0

@ Girre, можете ли вы предоставить образец Xml? – RePierre

ответ

3

Вы должны группировать узлы сотрудника значением 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()); 

Это, конечно, не является оптимальным решением, но это дает вам подсказку в правильном направлении. Отрегулируйте его в соответствии с вашими потребностями.

Edit II

файл из пасты бункера имеет 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()); 
+0

Можно ли удалить элементы, которые не являются последней версией этого идентификатора из xml-файла? А затем снова сохраните xml-файл? – Girre

+0

@ Girre, см. Редактирование. – RePierre

+0

Это замечательно, но не перезаписывает текущий xml-файл и сохраняет его. – Girre

0

Вы можете просто поместить данные в 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); 
     } 
    } 
} 

После этого у вас есть одна запись для каждого сотрудника с самой текущей датой.