Подтвердить что ты не робот

Добавление элементов в xml файл в С#

У меня есть XML файл, отформатированный следующим образом:

<Snippets>
  <Snippet name="abc">
    <SnippetCode>
      testcode1
    </SnippetCode>
  </Snippet>

  <Snippet name="xyz">
    <SnippetCode>      
     testcode2
    </SnippetCode>
  </Snippet>

  ...

</Snippets>

Я могу успешно загрузить элементы с помощью 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);

И в результате получится следующее:

<Snippet>
    <name>name goes here</name>
    <SnippetCode>
    code goes here
    </SnippetCode>
  </Snippet>

Он отлично работает, за исключением того, что тег имени генерируется неправильно. Это должно быть

<Snippet name="abc"> 

но я не могу сгенерировать это правильно.

4b9b3361

Ответ 1

Вы близко, но вы хотите, чтобы имя было 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); 

Ответ 2

Id будет склонен создавать классы, соответствующие структуре, и добавлять экземпляр в коллекцию, а затем сериализовать и десериализовать коллекцию для загрузки и сохранения документа.

Ответ 3

Если вы хотите добавить атрибут, а не элемент, вы должны сказать следующее:

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

В приведенном выше коде создается следующий XML-элемент:

<Snippet name="name goes here">
  <SnippetCode>SnippetCode</SnippetCode>
</Snippet> 

Ответ 4

Вам нужно создать новый XAttribute вместо XElement. Попробуйте что-то вроде этого:

        public static void Test()
        {
            var xdoc = XDocument.Parse(@"
<Snippets>
  <Snippet name='abc'>
    <SnippetCode>
      testcode1
    </SnippetCode>
  </Snippet>

  <Snippet name='xyz'>
    <SnippetCode>      
     testcode2
    </SnippetCode>
  </Snippet>

</Snippets>");

            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"?>
<Snippets>
  <Snippet name="abc">
    <SnippetCode>
      testcode1
    </SnippetCode>
  </Snippet>
  <Snippet name="xyz">
    <SnippetCode>      
     testcode2
    </SnippetCode>
  </Snippet>
  <Snippet name="name goes here">
    <SnippetCode>SnippetCode</SnippetCode>
  </Snippet>
</Snippets>

Ответ 5

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

Ответ 6

Это расширение для ответов выше, если ваш 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()+"Snippet" на parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet" например

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

Ответ 7

<Snippet name="abc"> 

name - это атрибут, а не элемент. Вот почему он терпит неудачу. Изучите использование SetAttribute в элементе <Snippet>.

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

- это код, который вам нужен, с тем, что у вас есть.