How do I merge 1 XML document into another, using Linq to XML where parent element equals other parent element

Stace Clark 1 Reputation point
2021-07-19T20:20:51.587+00:00

Hello,

I have been spinning my wheels here trying to merge a set of XML elements into other XML document (XDocument) where each document parent element equals each other.

So I have this Main XML document with Element "Name" to compare:

<Destinations>
  <Destination>
    <DestinationID>4</DestinationID>
    <MirthChannelID>65c47878-e2fe-4559-ae0a-ddf7f73d1e33</MirthChannelID>
    <MirthDestinationNumber>1</MirthDestinationNumber>
    **<Name>ADT Out - FFI</Name>**
    <Type>Channel Writer</Type>
    <Active>1</Active>
    <DestinationReference>a34e7994-ee4b-449e-b572-1d4433eeb5cd</DestinationReference>
    <QueuingEnabled>1</QueuingEnabled>
    <InsertDate>2021-06-14T10:55:52.5092442-07:00</InsertDate>
  </Destination>
  <Destination>
    <DestinationID>5</DestinationID>
    <MirthChannelID>65c47878-e2fe-4559-ae0a-ddf7f73d1e33</MirthChannelID>
    <MirthDestinationNumber>2</MirthDestinationNumber>
    **<Name>ADT Out - MPACS</Name>**
    <Type>Channel Writer</Type>
    <Active>1</Active>
    <DestinationReference>fc53efdf-22aa-4752-b1e4-75e0402b7881</DestinationReference>
    <QueuingEnabled>1</QueuingEnabled>
    <InsertDate>2021-06-14T10:55:52.5092442-07:00</InsertDate>
  </Destination>
</Destinations>

and I want to merge in this XML Data where the Above Element "Name" equals this Elements "ConnectorName"

<Destinations>
  <Destination>
    **<ConnectorName>ADT Out - FFI</ConnectorName>**
    <MessageStatuses>
      <MessageStatus>
        <Count>66</Count>
        <StatusType>S</StatusType>
      </MessageStatus>
    </MessageStatuses>
  </Destination>
  <Destination>
    **<ConnectorName>ADT Out - MPACS</ConnectorName>**
    <MessageStatuses>
      <MessageStatus>
        <Count>4</Count>
        <StatusType>S</StatusType>
      </MessageStatus>
    </MessageStatuses>
  </Destination>
</Destinations>

So essentially I want my new XML Document to look like this: (adding in the <MessageStatues> element and its children)

<Destinations>
      <Destination>
        <DestinationID>4</DestinationID>
        <MirthChannelID>65c47878-e2fe-4559-ae0a-ddf7f73d1e33</MirthChannelID>
        <MirthDestinationNumber>1</MirthDestinationNumber>
        **<Name>ADT Out - FFI</Name>**
        <Type>Channel Writer</Type>
        <Active>1</Active>
        <DestinationReference>a34e7994-ee4b-449e-b572-1d4433eeb5cd</DestinationReference>
        <QueuingEnabled>1</QueuingEnabled>
        <InsertDate>2021-06-14T10:55:52.5092442-07:00</InsertDate>
        <MessageStatuses>
          <MessageStatus>
            <Count>66</Count>
            <StatusType>S</StatusType>
          </MessageStatus>
        </MessageStatuses>
      </Destination>
      <Destination>
        <DestinationID>5</DestinationID>
        <MirthChannelID>65c47878-e2fe-4559-ae0a-ddf7f73d1e33</MirthChannelID>
        <MirthDestinationNumber>2</MirthDestinationNumber>
        **<Name>ADT Out - MPACS</Name>**
        <Type>Channel Writer</Type>
        <Active>1</Active>
        <DestinationReference>fc53efdf-22aa-4752-b1e4-75e0402b7881</DestinationReference>
        <QueuingEnabled>1</QueuingEnabled>
        <InsertDate>2021-06-14T10:55:52.5092442-07:00</InsertDate>
         <MessageStatuses>
          <MessageStatus>
            <Count>4</Count>
            <StatusType>S</StatusType>
          </MessageStatus>
        </MessageStatuses>
      </Destination>
 </Destinations>

I am trying to use C# XDocument and XElement to make this happen, but with no luck.

XDocument xml1 = XDocument.Parse(row.Destinations.ToString());
XElement x = xml1.Root.Descendants("Destination").First
if (row.DestinationPerformanceIndicators != null)
{
XDocument xml2 = XDocument.Parse(row.DestinationPerformanceIndicators.ToString());
//Combine and remove duplicates
StringBuilder sbu = new StringBuilder("<Destinations>");
foreach (var item in xml1.Descendants("Destinations").Union(xml2.Descendants("Destinations"), new MyComparer()))
{
sbu.Append(item);
}
sbu.Append("</Destinations>");
}

This code above is NOT working.. Please help if you have any ideas.
thank you !

Developer technologies ASP.NET Other
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Yijing Sun-MSFT 7,096 Reputation points
    2021-07-20T07:01:23.913+00:00

    Hi @Stace Clark ,
    As far as I think,you could find the node "Destination". And then you need to join these two xml files to select name equals ConnectorName.Just like this:

     var xml1 = XDocument.Load(@"C:\Users\yijings\source\repos\Webtest1\ConsoleApp5\XMLFile1.xml");  
                var xml2 = XDocument.Load(@"C:\Users\yijings\source\repos\Webtest1\ConsoleApp5\XMLFile2.xml");  
                var result = from e1 in xml1.Descendants().Elements("Destination")  
                             join e2 in xml2.Descendants().Elements("Destination")  
                             on e1.Element("Name").Value equals e2.Element("ConnectorName").Value  
                             select new XElement("Destination", new object[] { e1.Element("DestinationID"),  
                                 e1.Element("MirthChannelID"),  
                                 e1.Element("MirthDestinationNumber"),  
                                 e1.Element("Name"),  
                                 e1.Element("Type"),  
                                 e1.Element("Active"),  
                                 e1.Element("DestinationReference"),  
                                 e1.Element("QueuingEnabled"),  
                                 e2.Element("MessageStatuses")  
                             });  
                string file3 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +  
                   "<Destination>" +  
                   "</Destination>";  
                StringReader reader = new StringReader(file3);  
                XDocument newXDoc = XDocument.Load(reader);  
                newXDoc.Descendants("Destination").Last().Add(result);  
    

    Best regards,
    Yijing Sun


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our  documentation  to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.