I wish to merge two XML files, similar to What is the fastest way to combine two xml files into one
but I cannot wrap my head around how to group and merge them based on of the node values (Configuration node's Domain node value) I am trying it with Linq, but it doesn't make it easier, even the group by and where clause is there.
Basically I wish all Component nodes (duplicates are allowed) to be listed under the same Configuration node, which Domain name node values are equal.
In other words with the below example: the result XML has two Configuration nodes, one with Domain: MyDom01 the other is Domain: MyDom02 and under each configuration I have one Components node with all the Component listed.
Is that even possible?
One.XML
<System>
<Configurations>
<Configuration>
<Domain>MyDom01</Domain>
<Components>
<Component>
<Name>Memory</Name>
<Size>16</Size>
</Component>
<Component>
<Name>CPU</Name>
<Size>8</Size>
</Component>
</Components>
</Configuration>
<Configuration>
<Domain>MyDom01</Domain>
<Components>
<Component>
<Name>HDD</Name>
<Size>1</Size>
</Component>
</Components>
</Configuration>
<Configuration>
<Domain>MyDom02</Domain>
<Components>
<Component>
<Name>CPU</Name>
<Size>12</Size>
</Component>
</Components>
</Configuration>
</Configurations>
</System>
Another.XML
<System>
<Configurations>
<Configuration>
<Domain>MyDom01</Domain>
<Components>
<Component>
<Name>Memory</Name>
<Size>128</Size>
</Component>
<Component>
<Name>CPU</Name>
<Size>32</Size>
</Component>
<Component>
<Name>CPU</Name>
<Size>32</Size>
</Component>
</Components>
</Configuration>
<Configuration>
<Domain>MyDom02</Domain>
<Components>
<Component>
<Name>Memory</Name>
<Size>32</Size>
</Component>
</Components>
</Configuration>
</Configurations>
</System>
Merged.XML:
<System>
<Configurations>
<Configuration>
<Domain>MyDom01</Domain>
<Components>
<Component>
<Name>Memory</Name>
<Size>16</Size>
</Component>
<Component>
<Name>CPU</Name>
<Size>8</Size>
</Component>
<Component>
<Name>HDD</Name>
<Size>1</Size>
</Component>
<Component>
<Name>Memory</Name>
<Size>128</Size>
</Component>
<Component>
<Name>CPU</Name>
<Size>32</Size>
</Component>
<Component>
<Name>CPU</Name>
<Size>32</Size>
</Component>
</Components>
</Configuration>
<Configuration>
<Domain>MyDom02</Domain>
<Components>
<Component>
<Name>CPU</Name>
<Size>12</Size>
</Component>
<Component>
<Name>Memory</Name>
<Size>32</Size>
</Component>
</Components>
</Configuration>
</Configurations>
</System>
You can try to find <Components>
element with matching <Domain>
in XML1 then add <Component>
elements from XML2 to it, and add <Configuration>
from XML2 to <Configurations>
in XML1 if no such matching <Domain>
was found, for example:
var xdoc1 = XDocument.Load("path/to/xml1.xml");
var xdoc2 = XDocument.Load("path/to/xml2.xml");
foreach (var item in xdoc2.Descendants("Configuration"))
{
var domain = (string)item.Element("Domain");
// try to find <Components> with matching <Domain> in XML1
var parent = xdoc1.Descendants("Configuration")
.Where(o => (string)o.Element("Domain") == domain)
.Elements("Components")
.FirstOrDefault();
// if such <Components> is found, add <Component> from XML2 to it
if(parent != null)
{
parent.Add(item.Elements("Components").Elements("Component"));
}
// otherwise add <Configuration> from XML2 to <Configurations> in XML1
else
{
xdoc1.Root.Element("Configurations").Add(item);
}
}
// don't forget to save the modified XML1 if you need to
// here we only print the merged XML1
System.Console.WriteLine(xdoc1.ToString());
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments