Добавление элементов в 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">
но я не могу сгенерировать это правильно.
Ответы
Ответ 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");
- это код, который вам нужен, с тем, что у вас есть.