次のような形式の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">
しかし、適切に生成することはできません。
あなたは近いですが、名前を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);
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>
要素ではなく属性を追加する場合は、次のように言う必要があります。
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>
構造に一致するクラスを作成し、インスタンスをコレクションに追加してから、コレクションをシリアル化および非シリアル化して、ドキュメントをロードおよび保存します。
XDocument.Root . Add を使用して要素を追加しました。ルートは、 XElement を返します。これには、追加のXElementの追加機能があります
これは上記の回答の拡張です。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"));
_
<Snippet name="abc">
nameは属性であり、要素ではありません。それが失敗する理由です。 <Snippet>
要素でSetAttributeを使用して調べます。
root.SetAttribute("name", "name goes here");
あなたが持っているもので必要なコードです。