Обновить файл XML из списка <T> - PullRequest
1 голос
/ 02 декабря 2011

У меня есть XML-файл, содержащий записи вроде -

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfCLocation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <CLocation>
    <CId>5726</CId>
    <Long>0</Long>
    <Lat>0</Lat>
    <Status>Pending</Status>
  </CLocation>
  <CLocation>
    <CId>5736</CId>
    <Long>0</Long>
    <Lat>0</Lat>
    <Status>Processed</Status>        
  </CLocation>
</ArrayOfCLocation>

Я беру эти записи в Список как -

XDocument xDocument = XDocument.Load(filePath); 
List<T> list = xDocument.Descendants("CLocation")
     .Select(c => (new T()
     {
         CId = Convert.ToInt32(c.Descendants("CId").FirstOrDefault().Value),
         Lat = Convert.ToDouble(c.Descendants("Lat").FirstOrDefault().Value),
         Long = Convert.ToDouble(c.Descendants("Long").FirstOrDefault().Value),
         Status = (Status)Enum.Parse(typeof(Status), c.Descendants("Status").FirstOrDefault().Value)
     }))
     .Where(c => c.Status == Status.Pending)
     .Take(listCount)
     .ToList();

Теперь я обновляю объекты T (устанавливая их поля Lat / Log) в коллекции выше и после обработки этих объектов я хочу обновить эти записи обратно в файл XML.

Может ли кто-нибудь подсказать мне эффективное решение, как я могу обновить эти объекты обратно в файл XML.

1 Ответ

4 голосов
/ 02 декабря 2011

Вы можете сделать что-то вроде этого:

foreach (var location in list)
{
    var elem = xDocument.Root.Elements()
                        .Single(e => (int)e.Element("CId") == location.CId);
    elem.Element("Long").ReplaceNodes(location.Long);
    elem.Element("Lat").ReplaceNodes(location.Lat);
}

Затем вы можете сохранить измененный xDocument обратно в файл или что-то еще.

Если вы обнаружите, что это недостаточно эффективно, есть несколько способов ускорить процесс. Например, создайте Dictionary элементов с помощью CId, чтобы не выполнять поиск по всему документу каждый раз.

Но если у вас огромные файлы, загрузка их целиком в память может оказаться невозможной или хорошей идеей. Использование XmlReader и XmlWriter подойдет для файлов любого размера, но их не так просто использовать.

Другой вариант, который следует учитывать, - это сериализация XML. Это сделано специально для преобразования XML в ваши объекты и обратно.

Кроме того, код, который вы имеете, может быть значительно упрощен, и в процессе он будет сделан быстрее:

xDocument.Root.Elements("CLocation")
     .Select(c => new Location
                  {
                      CId = (int)c.Element("CId"),
                      Lat = (double)c.Element("Lat"),
                      Long = (double)c.Element("Long"),
                      Status = (Status)Enum.Parse(typeof(Status), c.Element("Status").Value)
                  })
...