Как вставить дочерний тег с помощью XDocument и XElement?

#c# #xml #xelement

#c# #xml #xelement

Вопрос:

У меня есть эта XML-схема, к которой мне нужно добавить дочерний тег:

 <?xml version="1.0" encoding="utf-8"?>
<PFA>
  <Entity id="123" action="add" date="04-Nov-2017"></Entity>
  <Entity id="125" action="add" date="05-Nov-2017"></Entity>
</PFA>
 

и ожидаемый результат:

 <?xml version="1.0" encoding="utf-8"?>
<PFA>
  <Record>
  <Entity id="123" action="add" date="04-Nov-2017"></Entity>
  <Entity id="125" action="add" date="05-Nov-2017"></Entity>
  </Record>
</PFA>
 

Я пробовал с этим кодом:

 var doc = XDocument.Load("data.xml");
var record = new XElement("Record");
doc.Element("PFA").Add(record);
doc.Save("data.xml");
 

Но мой результат приведен ниже. У него есть закрывающий тег, но в нем отсутствует открывающий тег.

 <?xml version="1.0" encoding="utf-8"?>
<PFA>
  <Entity id="123" action="add" date="04-Nov-2017">
   
  </Entity>
  </Record>
</PFA>
 

Обновлено:

Я попробовал это решение с Elements :

 var doc = XDocument.Load(file.FullName);
var record = new XElement("Record");
var pfa = doc.Element("PFA");
var entities = pfa.Elements("Entity");
entities.Remove();    // remove <Entity> from <PFA>
pfa.Add(record);    // add <Record> to <PFA>
record.Add(entities); // add <Entity> to <Record>
doc.Save(file.FullName);
 

Но все же тег открывающей записи отсутствует,

введите описание изображения здесь

и результат становится:

 <?xml version="1.0" encoding="utf-8"?>
<PFA>
  <Record />
</PFA>
 

Если я использую Element :

 var doc = XDocument.Load(file.FullName);
var record = new XElement("Record");
var pfa = doc.Element("PFA");
var entities = pfa.Element("Entity");
entities.Remove();    // remove <Entity> from <PFA>
pfa.Add(record);    // add <Record> to <PFA>
record.Add(entities); // add <Entity> to <Record>
doc.Save(file.FullName);
 

Вывод становится:

 <?xml version="1.0" encoding="utf-8"?>
<PFA>
  <Entity id="123" action="add" date="04-Nov-2017"></Entity></Record>
  <Record><Entity id="123" action="add" date="04-Nov-2017"></Entity></Record>
  <Record><Entity id="125" action="add" date="05-Nov-2017"></Entity></Record>
</PFA>
 

Комментарии:

1. Опубликованный вами код не создает этот недопустимый XML. Вместо этого он создает допустимый <Record /> тег. Вы уверены, что это тот XML, который вы получаете в данный момент?

Ответ №1:

Решение на самом деле довольно простое. Вы удаляете Entity теги из PFA тега, затем добавляете новый Record тег в PFA тег и переназначаете Entity теги в новый добавленный Record тег. Код может выглядеть следующим образом:

 var pfa = doc.Element("PFA");
IList<XElement> entities = pfa.Elements("Entity").ToList();
foreach (var entity in entities)
{
    entity.Remove(); // Remove all the <Entity> tags from <PFA>
}
var record = new XElement("Record");
pfa.Add(record); // Add the new <Record>
foreach (var entity in entities) 
{
    record.Add(entity); // Add the <Entity> tags back to <Record>
}
 

Комментарии:

1. Есть ли способ сделать это без удаления тега сущности? Потому что на самом деле файл содержит более 20 других тегов внутри тега PFA

2. Вы можете использовать Elements() вместо Element() , чтобы получить все дочерние элементы элемента, см. docs.microsoft.com/en-us/dotnet/api /. … Вам не нужно идентифицировать их по каждому отдельному имени.

3. Я пытался, Elements() но все еще не могу получить ожидаемый результат. Во pfa.Add(record) время отладки я вижу только закрывающий тег для записи. Не уверен, почему. Кстати, я обновил схему ожидаемого результата.

4. @Steve Проверьте мое обновление, я изменил его, чтобы использовать Elements() для получения всех дочерних элементов элемента. Вы можете использовать его, чтобы «отключить» все Entity элементы, затем добавить свой новый Record , а затем переадресовать все Entity элементы в новый Record элемент.