I have an XML file formatted like this:
我有一个这样的XML文件:
<Snippets>
<Snippet name="abc">
<SnippetCode>
testcode1
</SnippetCode>
</Snippet>
<Snippet name="xyz">
<SnippetCode>
testcode2
</SnippetCode>
</Snippet>
...
</Snippets>
I can successfully load the elements using XDocument, but I have trouble adding new elements (there are many functions and most of which I tried didn't work well for me). How would this be done? The new element would contain the snippet name tag and the snippet code tag. My previous approach was to open the file, and manually create the element using a string which although works, is a very bad idea.
我可以使用XDocument成功加载元素,但添加新元素时遇到了麻烦(有很多函数,我尝试过的大多数对我来说都不是很好)。怎么做呢?新元素将包含snippet name标记和snippet代码标记。我以前的方法是打开文件,然后使用一个字符串手工创建元素,虽然这个方法可行,但这是一个非常糟糕的想法。
What I have tried:
我已经尝试:
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);
And the result is this:
结果是:
<Snippet>
<name>name goes here</name>
<SnippetCode>
code goes here
</SnippetCode>
</Snippet>
It works fine except that the name tag is generated incorrectly. It should be
除了名称标签生成不正确之外,它工作得很好。它应该是
<Snippet name="abc">
but I can't generate that properly.
但我不能正确地生成它。
7 个解决方案
#1
46
You're close, but you want name to be an XAttribute
rather than XElement
:
您很接近了,但是您希望名称是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
4
Id be inclined to create classes that match the structure and add an instance to a collection then serialise and deserialise the collection to load and save the document.
Id倾向于创建与结构匹配的类,并向集合添加实例,然后序列化和反序列化集合以加载和保存文档。
#3
4
If you want to add an attribute, and not an element, you have to say so:
如果你想添加一个属性,而不是一个元素,你必须这样说:
XElement root = new XElement("Snippet");
root.Add(new XAttribute("name", "name goes here"));
root.Add(new XElement("SnippetCode", "SnippetCode"));
The code above produces the following XML element:
上面的代码生成以下XML元素:
<Snippet name="name goes here">
<SnippetCode>SnippetCode</SnippetCode>
</Snippet>
#4
4
You need to create a new XAttribute
instead of XElement
. Try something like this:
您需要创建一个新的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");
}
This generates the output:
这个生成的输出:
<?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
2
I've used XDocument.Root.Add to add elements. Root returns XElement which has an Add function for additional XElements
我用XDocument.Root。增加添加元素。根返回XElement,它对额外的XElement有一个Add函数。
#6
1
This is extension to answers above, if your xml has namespace defined (xmlns
) then you will get a nasty side effect when adding children - xmlns = ""
being added to your new child element.
这是对上面的答案的扩展,如果您的xml定义了名称空间(xmlns),那么在向新子元素添加子元素xmlns = ""时,您将得到一个令人讨厌的副作用。
What you want to do (assuming element you are adding belongs to same namespace as his parent) is to take namespace from parent element parentElement.GetDefaultNamespace()
.
您要做的(假设您要添加的元素与其父元素所属的名称空间相同)是从父元素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);
for parent elements with multiple namespaces you can choose which one to use by changing from parentElement.GetDefaultNamespace()+"Snippet"
to parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet"
e.g
对于具有多个名称空间的父元素,您可以通过从parentElement.GetDefaultNamespace()+“Snippet”到parentElement.GetNamespaceOfPrefix(“namespaceprefixthatgoeswith冒号”)+“Snippet”来选择要使用哪个名称空间。
var child = new XElement(parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet", new XAttribute("Attr1", "42"), new XAttribute("Attr2", "22"));
#7
0
<Snippet name="abc">
name is an attribute, not an element. That's why it's failing. Look into using SetAttribute on the <Snippet>
element.
名称是属性,而不是元素。这就是为什么失败。在
root.SetAttribute("name", "name goes here");
is the code you need with what you have.
是你所需要的代码。
#1
46
You're close, but you want name to be an XAttribute
rather than XElement
:
您很接近了,但是您希望名称是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
4
Id be inclined to create classes that match the structure and add an instance to a collection then serialise and deserialise the collection to load and save the document.
Id倾向于创建与结构匹配的类,并向集合添加实例,然后序列化和反序列化集合以加载和保存文档。
#3
4
If you want to add an attribute, and not an element, you have to say so:
如果你想添加一个属性,而不是一个元素,你必须这样说:
XElement root = new XElement("Snippet");
root.Add(new XAttribute("name", "name goes here"));
root.Add(new XElement("SnippetCode", "SnippetCode"));
The code above produces the following XML element:
上面的代码生成以下XML元素:
<Snippet name="name goes here">
<SnippetCode>SnippetCode</SnippetCode>
</Snippet>
#4
4
You need to create a new XAttribute
instead of XElement
. Try something like this:
您需要创建一个新的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");
}
This generates the output:
这个生成的输出:
<?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
2
I've used XDocument.Root.Add to add elements. Root returns XElement which has an Add function for additional XElements
我用XDocument.Root。增加添加元素。根返回XElement,它对额外的XElement有一个Add函数。
#6
1
This is extension to answers above, if your xml has namespace defined (xmlns
) then you will get a nasty side effect when adding children - xmlns = ""
being added to your new child element.
这是对上面的答案的扩展,如果您的xml定义了名称空间(xmlns),那么在向新子元素添加子元素xmlns = ""时,您将得到一个令人讨厌的副作用。
What you want to do (assuming element you are adding belongs to same namespace as his parent) is to take namespace from parent element parentElement.GetDefaultNamespace()
.
您要做的(假设您要添加的元素与其父元素所属的名称空间相同)是从父元素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);
for parent elements with multiple namespaces you can choose which one to use by changing from parentElement.GetDefaultNamespace()+"Snippet"
to parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet"
e.g
对于具有多个名称空间的父元素,您可以通过从parentElement.GetDefaultNamespace()+“Snippet”到parentElement.GetNamespaceOfPrefix(“namespaceprefixthatgoeswith冒号”)+“Snippet”来选择要使用哪个名称空间。
var child = new XElement(parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet", new XAttribute("Attr1", "42"), new XAttribute("Attr2", "22"));
#7
0
<Snippet name="abc">
name is an attribute, not an element. That's why it's failing. Look into using SetAttribute on the <Snippet>
element.
名称是属性,而不是元素。这就是为什么失败。在
root.SetAttribute("name", "name goes here");
is the code you need with what you have.
是你所需要的代码。