Добавление элементов в XML-файл в C # - PullRequest
31 голосов
/ 28 октября 2011

У меня есть 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"> 

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

Ответы [ 7 ]

57 голосов
/ 28 октября 2011

Вы близки, но вы хотите, чтобы имя было 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); 
6 голосов
/ 28 октября 2011

Вам нужно создать новый 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 голосов
/ 28 октября 2011

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

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 голосов
/ 28 октября 2011

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

2 голосов
/ 28 октября 2011

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

1 голос
/ 23 июня 2016

Это расширение к ответам выше, если в вашем 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" * 1011 например *

var child = new XElement(parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet", new XAttribute("Attr1", "42"), new XAttribute("Attr2", "22"));
0 голосов
/ 28 октября 2011
<Snippet name="abc"> 

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...