Linq to XML merge and add data?

Given XML as follows:

<Root> <Element> <Id>1</Id> </Element> <Element> <Id>2</Id> </Element> <Element> <Id>3</Id> </Element> </Root> 

And IEnumerable with this data:

 [0] = { Id = 1, Data = 429 } [1] = { Id = 2, Data = 271 } [2] = { Id = 3, Data = 328 } 

Is there an elegant way to use LINQ to XML to combine IEnumerable data with XML based on a common Id without an individual query for each element to bind data to?

Thus, the result will look like this:

 <Root> <Element> <Id>1</Id> <Data>429</Data> </Element> <Element> <Id>2</Id> <Data>271</Data> </Element> <Element> <Id>3</Id> <Data>328</Data> </Element> </Root> 

The only thing I can think of is something like this, but I was hoping there was a cleaner method:

 foreach(var d in MyIEnumerable) { XElement element = (from x in MyXDoc.Elements("Element") where x.Element("Id").Value == d.Id select x).Single(); element.Add(new XElement("Data", d.Data)); } 
+4
source share
2 answers

One way is to use Tuple<Element, XElement> . ( Element is a class that has an ID and data in it.)

 var output = from el in els join xmlEl in xdoc.Root.Elements("Element") on el.Id equals int.Parse(xmlEl.Element("Id").Value) select new Tuple<Element, XElement>(el, xmlEl); foreach(var item in output) { item.Item2.Add(new XElement("Data", item.Item1.Data)); } 

If you don't have tuples, you can create an anonymous class.

 select new {ObjEl = el, XmlEl = xmlEl} 
+3
source

You might be able to do something like:

 var elements = MyXDoc.Elements("Element"); elements.Apply(e => e.Add(new XElement("Data", MyIEnumerable.FirstOrDefault(d => d.Id == e.Element("Id").Value).Data))); 

Where the Apply extension method is defined as:

 public static class Extensions { public static void Apply<T>(this IEnumerable<T> enumerable, Action<T> action) { foreach (var item in enumerable) { action(item); } } } 
+1
source

Source: https://habr.com/ru/post/1345535/


All Articles