Merging and concatenating similiar records with linq to xml
-
Here's another one I'm hoping you guys could help me with. I have an XML structure (example below) which is dynamically generated from a flat file. The sources vary, so the structure of the XML will differ from one execution to the next. What I need to achieve is to merge similar records in the XML data into one record, where some fields are merged, and some concatenated. The user specifies which field is the 'Key' field, and which one(s) is/are the concatenation fields. For example, in the following XML, the 'EMail' field is the key, while the 'ListDescription' is to be concatenated:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<SourceContactList_Root>
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 1</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 2</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 3</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>
</SourceContactList_Root>The result I'm looking for is this:
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 1;List Type 2;List Type 3</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>Note that the 'ListDescription' field values for the three records where concatenated with a ; separator.
-
Here's another one I'm hoping you guys could help me with. I have an XML structure (example below) which is dynamically generated from a flat file. The sources vary, so the structure of the XML will differ from one execution to the next. What I need to achieve is to merge similar records in the XML data into one record, where some fields are merged, and some concatenated. The user specifies which field is the 'Key' field, and which one(s) is/are the concatenation fields. For example, in the following XML, the 'EMail' field is the key, while the 'ListDescription' is to be concatenated:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<SourceContactList_Root>
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 1</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 2</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 3</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>
</SourceContactList_Root>The result I'm looking for is this:
<SourceContactList>
<EMail>bobsmith@acme.com</EMail>
<ListDescription>List Type 1;List Type 2;List Type 3</ListDescription>
<Title>Mr.</Title>
<Firstname>Bob</Firstname>
<Surname>Smith</Surname>
<JobTitle>Administration Manager</JobTitle>
<CompanyName>Acme Inc</CompanyName>
</SourceContactList>Note that the 'ListDescription' field values for the three records where concatenated with a ; separator.
Ok, I'm not a Linq to XML expert, but here's my little attempt to get your "List Type 1; List Type 2; List Type 3" string:
XDocument doc = XDocument.Load("Source.xml");
var listDescriptions = from node in doc.DescendantNodes()
let element = node as XElement
where element != null && element.Name == "ListDescription"
select element.Value;var concatenatedListDescriptions = listDescriptions.Aggregate((in1, in2) => in1 + ";" + in2);
After that, you've got your concatenated ListDescription. All that's left is writing the final document with this concatenated string in there. FWIW, I used this Linq to XML article[^] to figure out some stuff. Also, the Aggregate call that actually concats the strings together not optimal - ideally you'd have a StringBuilder that pieces them together.
Life, family, faith: Give me a visit. From my latest post: "How differently the psalmist saw it! How blessed -- how truly happy with real joy! -- is the man who delights in the Law of the Lord." Judah Himango