2013-10-02 3 views
2

У меня есть элементы 2 XML (из разных документов XML с одной и той же схеме) одного и того же типа вида:Merge XML узлы одного типа в C#

<Parent> 
    <ChildType1>contentA</ChildType1> 
    <ChildType2>contentB</ChildType2> 
    <ChildType3>contentC</ChildType3> 
</Parent> 

<Parent> 
    <ChildType1>contentD</ChildType1> 
    <ChildType3>contentE</ChildType3> 
</Parent> 

Типы элементов ChildType1, ChildType2 и ChildType3 может иметь не более одного экземпляра в элементе «Родитель».

Что мне нужно сделать, это объединить содержание второго родительского узла с первым родительским узлом в новый узел, который будет выглядеть следующим образом:

<Parent> 
    <ChildType1>contentD</ChildType1> 
    <ChildType2>contentB</ChildType2> 
    <ChildType3>contentE</ChildType3> 
</Parent> 
+1

Вы не хотите копировать второй узел в первый, вы хотите переписать первый на второй. Или результат вашего образца неверен. –

+0

Перезапись узла означает, что результат не будет содержать элемент . Но я согласен, что копия - это не лучший термин. – vicch

ответ

3

Использование Linq для XML для анализа исходных документов. Затем создайте соединение между ними и группируйте по имени элемента и создайте новый документ, используя первые/последние элементы в группах в зависимости от того, что вы хотите.

Что-то вроде этого:

var doc = XElement.Parse(@" 
    <Parent> 
     <ChildType1>contentA</ChildType1> 
     <ChildType2>contentB</ChildType2> 
     <ChildType3>contentC</ChildType3> 
    </Parent> 
"); 

var doc2 = XElement.Parse(@" 
    <Parent> 
     <ChildType1>contentD</ChildType1> 
     <ChildType3>contentE</ChildType3> 
    </Parent> 
"); 

var result = 
    from e in doc.Elements().Union(doc2.Elements()) 
    group e by e.Name into g 
    select g.Last(); 
var merged = new XDocument(
    new XElement("root", result) 
); 

merged теперь содержит

<root> 
    <ChildType1>contentD</ChildType1> 
    <ChildType2>contentB</ChildType2> 
    <ChildType3>contentE</ChildType3> 
</root> 
+0

спасибо, это сработало! – vicch

1

Если вы назвать два исходных документов, как xd0 и xd1 тогда это работало для меня:

var nodes = 
    from xe0 in xd0.Root.Elements() 
    join xe1 in xd1.Root.Elements() on xe0.Name equals xe1.Name 
    select new { xe0, xe1, }; 

foreach (var node in nodes) 
{ 
    node.xe0.Value = node.xe1.Value; 
} 

I получил этот результат:

<Parent> 
    <ChildType1>contentD</ChildType1> 
    <ChildType2>contentB</ChildType2> 
    <ChildType3>contentE</ChildType3> 
</Parent> 
+0

спасибо за ответ, это сработало, но я нахожу ответ Микаэля немного яснее. – vicch

+1

@vicch. Все в порядке, но ваш вопрос попросил заменить узлы в первом xml, а не создать совершенно новый документ. Я бы подумал, что я технически более точен? – Enigmativity

+0

Вы правы, я редактировал вопрос. Надеюсь, он ближе к тому, что я хотел сейчас. – vicch