У меня есть два XML-файла, OriginalXML и UpdatesXML, которые мне нужно объединить и сохранить только последние изменения. Мои пользователи по существу получают копию OriginalXML, вносят изменения, а затем отправляют обновления веб-службе. Мне нужно только обновить OriginalXML узлами, которые новее в UpdatesXML.C# объединить только XML последний узел
я могу перебирать узлы в UpdatesXML, сделайте поиск в OriginalXML на матч, проверить метку времени и заменить его, если обновления новее: (что-то вроде)
var OriginalXML = XDocument.Load("Original.xml");
var UpdatesXML = XDocument.Load("Updates.xml");
foreach (XElement WigitNode in UpdatesXML.Descendants("Wigit"))
{
//Find the corresponding OriginalXML node based on the Wigit/Subnode1/Id attribute
//Replace Original/Wigit with Updates/Wigit if Updates/Wigit/Editstamp/Timestamp attribute is later in Updates than Original
}
Всю эту вещь кажется довольно неуклюжим для меня, особенно если у Updates.xml много узлов. Мой вариант использования, вероятно, десятки за раз, поэтому это может быть не проблема, но кажется неэффективной. Есть ли простое преобразование XPath или xslt или что-то, что было бы быстрее или эффективнее?
Мой XML выглядит следующим образом: Original.xml:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Wigit>
<EditStamp UserId="timmy" Timestamp="2013-09-13T20:22:00" />
<Subnode1 Id="A" />
</Wigit>
<Wigit>
<EditStamp UserId="phil" Timestamp="2013-09-13T21:51:00" />
<Subnode1 Id="B" />
</Wigit>
<Wigit>
<EditStamp UserId="biff" Timestamp="2013-10-13T21:51:00" />
<Subnode1 Id="C" />
</Wigit>
</Root>
Updates.xml:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Wigit>
<EditStamp UserId="frank" Timestamp="2013-10-13T22:00:00" />
<Subnode1 Id="A" />
</Wigit>
</Root>
И желаемый результат:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Wigit>
<EditStamp UserId="frank" Timestamp="2013-10-13T22:00:00" />
<Subnode1 Id="A" />
</Wigit>
<Wigit>
<EditStamp UserId="phil" Timestamp="2013-09-13T21:51:00" />
<Subnode1 Id="B" />
</Wigit>
<Wigit>
<EditStamp UserId="biff" Timestamp="2013-10-13T21:51:00" />
<Subnode1 Id="C" />
</Wigit>
</Root>
UPDATE: 10 -15-2013
Я сделал некоторые возился с помощью кода Abhijeet Патела ниже и пришел с этим:
var query = from o in docOriginal.Element("Root").Elements("Wigit")
from u in docUpdate.Element("Root").Elements("Wigit")
let x = docUpdate.Element("Root")
.Elements("Wigit")
.SingleOrDefault(e => (e.Element("Subnode1").Attribute("id").Value == o.Element("Subnode1").Attribute("id").Value &&
DateTime.Parse(e.Element("EditStamp").Attribute("Timestamp").Value).Ticks > DateTime.Parse(o.Element("EditStamp").Attribute("Timestamp").Value).Ticks)) ?? o
select x;
XDocument merged = new XDocument(new XElement("Root", query));
return merged;
Это дает правильный результат, за исключением, что каждый узел дублируется:
<Root>
<Wigit>
<EditStamp UserId="frank" Timestamp="2013-10-13T22:00:00" />
<Subnode1 Id="SomeNewThing" />
</Wigit>
<Wigit>
<EditStamp UserId="frank" Timestamp="2013-10-13T22:00:00" />
<Subnode1 Id="SomeNewThing" />
</Wigit>
<Wigit>
<EditStamp UserId="phil" Timestamp="2013-09-13T21:51:00" />
<Subnode1 Id="B" />
</Wigit>
<Wigit>
<EditStamp UserId="phil" Timestamp="2013-09-13T21:51:00" />
<Subnode1 Id="B" />
</Wigit>
<Wigit>
<EditStamp UserId="biff" Timestamp="2013-10-13T21:51:00" />
<Subnode1 Id="C" />
</Wigit>
<Wigit>
<EditStamp UserId="biff" Timestamp="2013-10-13T21:51:00" />
<Subnode1 Id="C" />
</Wigit>
</Root>
Любые намеки о том, как не дублировать результаты?
Обновление 10-16-2013:
Причина я получаю повторяющиеся результаты потому, что документ обновления я использовал два узла. Код должен обрабатывать сразу несколько изменений, обновляя только узлы с большей меткой времени.
string update = @"<?xml version='1.0' encoding='utf-8'?>
<Root>
<Wigit id='A'>
<EditStamp UserId='frank' Timestamp='2013-10-13T22:00:00' />
<Subnode1 Id='SomeNewThing' />
</Wigit>
<Wigit id='B'>
<EditStamp UserId='yomamma' Timestamp='2013-09-10T21:51:00' />
<Subnode1 Id='B' />
</Wigit>
</Root>";
Это действительно очень близко к тому, что мне нужно одна небольшая проблема является результатом этого запроса имеет каждый узел в его собственном узле (и пугающе просто!). ' ... –
nickvans
Надзор с моей стороны во время отладки. Я обновил ответ. Как правило, выбор в запросе Linq необходимо сделать «выбрать x». Попробуйте сейчас :-) –
Ты мой герой! Большое вам спасибо за помощь! – nickvans