Додавання елементів у файл XML у C #

У мене є XML-файл, форматований таким чином:


  
    
      testcode1
    
  

  
          
     testcode2
    
  

  ...


Я можу успішно завантажувати елементи за допомогою XDocument, але у мене є проблеми з додаванням нових елементів (є багато функцій, більшість з яких я спробував, не для мене добре). Як це буде зроблено? Новий елемент міститиме тег імені фрагменту та тег коду фрагменту. Мій попередній підхід полягав у тому, щоб відкрити файл, і вручну створити елемент за допомогою ланцюжка, який, хоча й працює, є дуже поганою ідеєю.

Що я спробував:

XDocument doc = XDocument.Load(spath);
XElement root = new XElement("Snippet");
root.Add(new XElement("name", "name goes here"));
root.Add(new XElement("SnippetCode", "SnippetCode"));
doc.Element("Snippets").Add(root);
doc.Save(spath);

І результат це:


    name goes here
    
    code goes here
    

Він чудово працює, крім того, що тег імені створене неправильно. Вона повинна бути

 

але я не можу генерувати це належним чином.

26
Оскільки ви маєте існуючий "root", ви можете перейменувати цей код .... "XElement root = new XElement (" Snippet ");" ... Я думаю, це призвело до деякої вашої плутанини. Приклад: XElement newSnippetElement = новий XElement ("Фрагмент");
додано Автор granadaCoder, джерело
Покажіть, що ви пробували. Це не повинно бути складним за допомогою XElement.Add .
додано Автор Matthew Flaschen, джерело
Див. Мій відредагований пост. Я дав вам приклад однієї з моїх невдалої (але дещо близької) спроби.
додано Автор rayanisran, джерело

7 Відповіді

Ви близькі, але ви хочете, щоб ім'я було XAttribute , а не XElement :

 XDocument doc = XDocument.Load(spath); 
 XElement root = new XElement("Snippet"); 
 root.Add(new XAttribute("name", "name goes here")); 
 root.Add(new XElement("SnippetCode", "SnippetCode")); 
 doc.Element("Snippets").Add(root); 
 doc.Save(spath); 
46
додано
Я бачу, що я мав використовувати атрибут для імені. Дякую, що виправив мене.
додано Автор rayanisran, джерело

Якщо ви хочете додати атрибут, а не елемент, вам слід сказати так:

XElement root = new XElement("Snippet");
root.Add(new XAttribute("name", "name goes here"));
root.Add(new XElement("SnippetCode", "SnippetCode"));

Наведений вище код видає наступний елемент XML:


  SnippetCode
 
5
додано

Вам потрібно створити новий XAttribute замість XElement . Спробуйте щось на зразок цього:

public static void Test()
{
    var xdoc = XDocument.Parse(@"
        

          
            
              testcode1
            
          

          
                  
             testcode2
            
          

        ");

    xdoc.Root.Add(
        new XElement("Snippet",
            new XAttribute("name", "name goes here"),
            new XElement("SnippetCode", "SnippetCode"))
    );
    xdoc.Save(@"C:\TEMP\FOO.XML");
}

Це генерує результат:

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

  
    
      testcode1
    
  
  
          
     testcode2
    
  
  
    SnippetCode
  

4
додано

Id буде схильний створювати класи, які відповідають структурі та додають екземпляр у колекцію, а потім серіалізують і десеріалізують колекцію для завантаження та збереження документа.

4
додано

Я використав XDocument.Root . Додати , щоб додати елементи. Корень повертає XElement , який має функцію Add для додаткові елементи XElements

2
додано
Здається, ви забули закінчити вирок.
додано Автор svick, джерело
так здається. оновлено
додано Автор Rob Haupt, джерело

Це розширення до відповідей вище, якщо вашому xml визначено простір імен ( xmlns ), то ви отримаєте неприємний побічний ефект, додаючи до вашої дитини - xmlns = "" до вашого новий дочірній елемент

Те, що ви хочете зробити (вважаючи, що доданий елемент належить до того самого простору імен, що і його батько), полягає в тому, щоб взяти простір імен з батьківського елемента parentElement.GetDefaultNamespace() .

var child = new XElement(parentElement.GetDefaultNamespace()+"Snippet", new XAttribute("Attr1", "42"), new XAttribute("Attr2", "22"));
child.Add(new XAttribute("Attr3", "777"));
parentElement.Add(child);

для батьківських елементів з декількома просторами імен ви можете вибрати, який з них використовувати, перейшовши з parentElement.GetDefaultNamespace() + "фрагмента" в parentElement.GetNamespaceOfPrefix ("namespacePrefixThatGoesWithColon") + "фрагмент" наприклад

var child = new XElement(parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet", new XAttribute("Attr1", "42"), new XAttribute("Attr2", "22"));
1
додано
 

name is an attribute, not an element. That's why it's failing. Look into using SetAttribute on the element.

root.SetAttribute("name", "name goes here");

це код, який вам потрібний, з тим, що у вас є.

0
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug