Слияние двух XDocument - PullRequest
       8

Слияние двух XDocument

0 голосов
/ 14 января 2019

У меня есть два xml, я должен объединить определенный узел

Это первый:

<ContactEmployees>
  <row>
    <Name>NAME</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>11</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <FirstName>Tizio</FirstName>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
  </row>
</ContactEmployees>

Это второе:

<ContactEmployees>
      <row>
        <CardCode>1000010</CardCode>
        <Name>NAME</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>Prova</Name>
        <InternalCode>2703</InternalCode>
        <PlaceOfBirth>-1</PlaceOfBirth>
        <Gender>gt_Undefined</Gender>
        <Active>tYES</Active>
        <FirstName>Prova</FirstName>
        <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
      </row>
    </ContactEmployees>

Это результат, который я ожидаю после слияния:

<ContactEmployees>
       <row>
        <Name>NAME</Name>
        <Position>Mag</Position>
        <Phone1>number</Phone1>
        <E_Mail>mail</E_Mail>
        <InternalCode>11</InternalCode>
        <Gender>gt_Undefined</Gender>
        <Active>tYES</Active>
        <FirstName>Tizio</FirstName>
        <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
      </row>
      <row>
        <CardCode>1000010</CardCode>
        <Name>Prova</Name>
        <InternalCode>2703</InternalCode>
        <PlaceOfBirth>-1</PlaceOfBirth>
        <Gender>gt_Undefined</Gender>
        <Active>tYES</Active>
        <FirstName>Prova</FirstName>
        <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
      </row>
    </ContactEmployees>

пытаюсь сделать IEnumerable<XElement> merge = xdoc.Root.Descendants("ContactEmployees").Concat("ContactEmployees")); xdoc - это весь мой xml-документ, частью которого является узел «ContactEmployees», но метод concat генерирует xml с тремя узлами или ставит в очередь все узлы, я пробовал объединение, но исключает второй xml, и я не понимаю, как я могу это сделать, возможно, с запросом, пытающимся видеть через атрибут InternalCode, потому что я не могу изменить его так, чтобы он был уникальным?

-Edit- Я рассмотрел ситуацию, Internalcode может отличаться (это данные базы данных), и Name может изменить его (Name, InternalCode и CardCode являются ключом моей таблицы), поэтому мне фактически нужно объединить изменения в одной строке и добавить из второго xml новые строки, я не знаю, насколько это возможно

1 Ответ

0 голосов
/ 14 января 2019

Вот решение с явным циклом foreach:

var doc = XDocument.Parse(@"<ContactEmployees>
  <row>
    <Name>NAME</Name>
    <Position>Mag</Position>
    <Phone1>number</Phone1>
    <E_Mail>mail</E_Mail>
    <InternalCode>11</InternalCode>
    <Gender>gt_Undefined</Gender>
    <Active>tYES</Active>
    <FirstName>Tizio</FirstName>
    <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
  </row>
</ContactEmployees>");

var doc2 = XDocument.Parse(@"<ContactEmployees>
      <row>
        <CardCode>1000010</CardCode>
        <Name>NAME</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>Prova</Name>
        <InternalCode>2703</InternalCode>
        <PlaceOfBirth>-1</PlaceOfBirth>
        <Gender>gt_Undefined</Gender>
        <Active>tYES</Active>
        <FirstName>Prova</FirstName>
        <BlockSendingMarketingContent>tNO</BlockSendingMarketingContent>
      </row>
    </ContactEmployees>");

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;
        }
    }
}

Полученный XML находится в doc.

...