locked
How to merge two xml RRS feed

  • Question

  • User-1248511554 posted

    I have this situation before the change (the changes come from a management application from which the xml recovery and then propagate with a service on another db):

    xml1
    <ContactEmployees>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>11</InternalCode> -->InternalCode is different on the two db
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    </ContactEmployees>

    xml2
    <ContactEmployees>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>101</InternalCode> -->InternalCode is different on the two db
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME_N</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>4101</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    </ContactEmployees>

    after change
    xml1
    <ContactEmployees>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME2</Name> ---> modify the name
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>11</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    </ContactEmployees>

    The result I would like to get is:

    xml that updates on the second database
    <ContactEmployees>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME2</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>101</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME_N</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>4101</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    </ContactEmployees>

    Instead I find myself:
    xml that updates on the second database
    <ContactEmployees>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME2</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>11</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME2</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>101</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME_N</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>4101</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    </ContactEmployees>

    this piece of code I've tried provokes the error described above but I have no idea how I can get the desired results

    var employees = doc.Root;

    var employees2 = doc2.Root;

    foreach (var row2 in employees2.Elements("row"))
    {
    // the following may be adapted to whatever criterion shall be used
    // to identify a record
    var id2 = row2.Element("InternalCode").Value;
    var row = employees.Elements("row").FirstOrDefault(r => r.Element("InternalCode").Value == id2);

    if (row == null)
    {
    // row not found in doc, so add it
    employees.Add(row2);
    }
    else
    {
    // row found; maybe update it, e.g.
    var nameElement2 = row2.Element("Name");
    if (nameElement2 != null)
    {
    var nameElement = row.Element("Name");
    if (nameElement == null)
    nameElement = nameElement2;
    else
    nameElement.Value = nameElement2.Value;
    }
    }
    }

    Tuesday, January 15, 2019 1:45 PM

All replies

  • User-1174608757 posted

    Hi shaun87RP,

    var row = employees.Elements("row").FirstOrDefault(r => r.Element("InternalCode").Value == id2);

    This code means you will get the row in  XML1 which has the same InternalCode in XML2 else it will return null. However I found , the InternalCode of row in XML  is different from that of the two rows in XML2. So it is absolute that it will add two rows in XML1 which means you will get three rows in XML1.

    To realize your requirement , you should keep the InternalCode of one row in XML2 same as that in XML1.  I have made a sample here. I hope it could help you.

    XML1:

    <ContactEmployees>
    <row>
    <CardCode>1000010</CardCode>
    <Name>WHATEVER</Name> 
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>101</InternalCode> 
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    </ContactEmployees>

    XML2:

    <ContactEmployees>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME2</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>101</InternalCode> <!--Confirm this is same as row in XML1-->
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    <row>
    <CardCode>1000010</CardCode>
    <Name>NAME_N</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>4101</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
    </row>
    </ContactEmployees>

    Best Regards 

    Wei Zhang

    Wednesday, January 16, 2019 6:19 AM
  • User-1248511554 posted

    Thanks, the problem is that I do not know how much the InternalCodes are worth, are assigned automatically by the program, and I can not even modify them manually to avoid key errors violated or duplicated

    Wednesday, January 16, 2019 8:17 AM
  • User-1174608757 posted

    Hi shaun87RP,

    According to your description, could you post more details about your requirement?Do you just want to replace the InternalCodes  of row in XML1 with that of the frist row in XML2? If so ,you could use the code as below.

    var employees = doc.Root;
    
                var employees2 = doc2.Root;
                
                 var row2 = employees2.Elements("row").ToArray();
                var row = employees.Elements("row").FirstOrDefault();
              
                var a = row2[0].Element("InternalCode").Value;
                row.Element("InternalCode").Value = a;

    If not, please tell me what you want , I will solve it  as soon as possible

    Best regards

    Wei Zhang

    Wednesday, January 16, 2019 10:17 AM