Asked by:
How to merge two xml

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 resultsvar 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