C#で有効なXMLを生成するにはどうすればよいですか?
C#で有効なXMLを生成するにはどうすればよいですか?
回答:
シナリオによって異なります。XmlSerializer
確かに1つの方法であり、オブジェクトモデルに直接マッピングできるという利点があります。.NET 3.5ではXDocument
、などもとてもフレンドリーです。サイズが非常に大きい場合XmlWriter
は、あなたの友達です。
以下の場合XDocument
の例:
Console.WriteLine(
new XElement("Foo",
new XAttribute("Bar", "some & value"),
new XElement("Nested", "data")));
または同じXmlDocument
:
XmlDocument doc = new XmlDocument();
XmlElement el = (XmlElement)doc.AppendChild(doc.CreateElement("Foo"));
el.SetAttribute("Bar", "some & value");
el.AppendChild(doc.CreateElement("Nested")).InnerText = "data";
Console.WriteLine(doc.OuterXml);
大量のデータストリームを書き込んでいる場合、DOMのアプローチ(XmlDocument
/ XDocument
など)はすぐに大量のメモリを消費します。したがって、CSVから100 MBのXMLファイルを作成する場合は、検討することをお勧めしますXmlWriter
。これはより原始的(1回限りのファイアホース)ですが、非常に効率的です(ここで大きなループを想像してください)。
XmlWriter writer = XmlWriter.Create(Console.Out);
writer.WriteStartElement("Foo");
writer.WriteAttributeString("Bar", "Some & value");
writer.WriteElementString("Nested", "data");
writer.WriteEndElement();
最後に、経由XmlSerializer
:
[Serializable]
public class Foo
{
[XmlAttribute]
public string Bar { get; set; }
public string Nested { get; set; }
}
...
Foo foo = new Foo
{
Bar = "some & value",
Nested = "data"
};
new XmlSerializer(typeof(Foo)).Serialize(Console.Out, foo);
これはクラスへのマッピングなどに適したモデルです。ただし、単純なことをしている場合(または、目的のXMLにオブジェクトモデルとの直接的な相関関係がない場合)は、やり過ぎになる可能性があります。もう1つの問題XmlSerializer
は、不変の型をシリアル化することを好まないことです。すべてをパブリックゲッターとセッターに設定する必要があります(ただし、を実装してすべてを自分IXmlSerializable
で行う場合は、を使用してもそれほど多くは得られませんXmlSerializer
)。
私が試した中で最も良いことは、LINQ to XSD(ほとんどの開発者には不明です)です。XSDスキーマを指定すると、完全にマッピングされた完全に厳密に型指定されたオブジェクトモデル(LINQ to XMLに基づく)がバックグラウンドで生成されます。これは非常に使いやすく、オブジェクトモデルとXMLを更新して検証しますリアルタイム。まだ「プレビュー」ですが、バグは発生していません。
次のようなXSDスキーマがある場合:
<xs:element name="RootElement">
<xs:complexType>
<xs:sequence>
<xs:element name="Element1" type="xs:string" />
<xs:element name="Element2" type="xs:string" />
</xs:sequence>
<xs:attribute name="Attribute1" type="xs:integer" use="optional" />
<xs:attribute name="Attribute2" type="xs:boolean" use="required" />
</xs:complexType>
</xs:element>
次に、次のようにXMLを作成するだけです。
RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootElement.Element2 = "Element2";
rootElement.Attribute1 = 5;
rootElement.Attribute2 = true;
または、単に次のようにファイルからXMLをロードします。
RootElement rootElement = RootElement.Load(filePath);
または、次のように保存します。
rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);
rootElement.Untyped
また、要素をXElement(LINQからXML)の形式で生成します。
RootElement
XmlWriterは、優れたXMLを作成する最速の方法です。XDocument、XMLDocumentなども同様に機能しますが、XMLの書き込み用に最適化されていません。XMLを可能な限り高速に記述したい場合は、必ずXmlWriterを使用する必要があります。
過去にXMLスキーマを作成し、ツールを使用して、そのスキーマにシリアル化するC#クラスを生成しました。XMLスキーマ定義ツールはその一例です
http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx
このリソースは、適度なXMLの保存/読み込み(C#を使用したXMLの読み取り/書き込み)には十分であると思います。
私の仕事は楽譜を保存することでした。.NETはタスクの簡単な解決を可能にするのに十分成熟していると思いますので、私はXMLを選択します。私は正しかったです :)
これは私の曲ファイルのプロトタイプです:
<music judul="Kupu-Kupu yang Lucu" pengarang="Ibu Sud" tempo="120" birama="4/4" nadadasar="1=F" biramapembilang="4" biramapenyebut="4">
<not angka="1" oktaf="0" naikturun="" nilai="1"/>
<not angka="2" oktaf="0" naikturun="" nilai="0.5"/>
<not angka="5" oktaf="1" naikturun="/" nilai="0.25"/>
<not angka="2" oktaf="0" naikturun="\" nilai="0.125"/>
<not angka="1" oktaf="0" naikturun="" nilai="0.0625"/>
</music>
それは非常に簡単に解決できます:
ファイルに保存する場合:
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog1.Title = "Save Song File";
saveFileDialog1.Filter = "Song Files|*.xsong";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create);
XmlTextWriter w = new XmlTextWriter(fs, Encoding.UTF8);
w.WriteStartDocument();
w.WriteStartElement("music");
w.WriteAttributeString("judul", Program.music.getTitle());
w.WriteAttributeString("pengarang", Program.music.getAuthor());
w.WriteAttributeString("tempo", Program.music.getTempo()+"");
w.WriteAttributeString("birama", Program.music.getBirama());
w.WriteAttributeString("nadadasar", Program.music.getNadaDasar());
w.WriteAttributeString("biramapembilang", Program.music.getBiramaPembilang()+"");
w.WriteAttributeString("biramapenyebut", Program.music.getBiramaPenyebut()+"");
for (int i = 0; i < listNotasi.Count; i++)
{
CNot not = listNotasi[i];
w.WriteStartElement("not");
w.WriteAttributeString("angka", not.getNot() + "");
w.WriteAttributeString("oktaf", not.getOktaf() + "");
String naikturun="";
if(not.isTurunSetengah())naikturun="\\";
else if(not.isNaikSetengah())naikturun="/";
w.WriteAttributeString("naikturun",naikturun);
w.WriteAttributeString("nilai", not.getNilaiNot()+"");
w.WriteEndElement();
}
w.WriteEndElement();
w.Flush();
fs.Close();
}
}
ロードファイルの場合:
openFileDialog1.Title = "Open Song File";
openFileDialog1.Filter = "Song Files|*.xsong";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);
XmlTextReader r = new XmlTextReader(fs);
while (r.Read())
{
if (r.NodeType == XmlNodeType.Element)
{
if (r.Name.ToLower().Equals("music"))
{
Program.music = new CMusic(r.GetAttribute("judul"),
r.GetAttribute("pengarang"),
r.GetAttribute("birama"),
Convert.ToInt32(r.GetAttribute("tempo")),
r.GetAttribute("nadadasar"),
Convert.ToInt32(r.GetAttribute("biramapembilang")),
Convert.ToInt32(r.GetAttribute("biramapenyebut")));
}
else
if (r.Name.ToLower().Equals("not"))
{
CNot not = new CNot(Convert.ToInt32(r.GetAttribute("angka")), Convert.ToInt32(r.GetAttribute("oktaf")));
if (r.GetAttribute("naikturun").Equals("/"))
{
not.setNaikSetengah();
}
else if (r.GetAttribute("naikturun").Equals("\\"))
{
not.setTurunSetengah();
}
not.setNilaiNot(Convert.ToSingle(r.GetAttribute("nilai")));
listNotasi.Add(not);
}
}
else
if (r.NodeType == XmlNodeType.Text)
{
Console.WriteLine("\tVALUE: " + r.Value);
}
}
}
}
}
単純なケースでは、XmlOutputを見て、Xml を作成するための流暢なインターフェイスも検討することをお勧めします。
XmlOutputは、有効なXmlを生成しながら、読み取り可能で保守可能なコードを使用した単純なXml作成に最適です。元の投稿にはいくつかの素晴らしい例があります。
上記のように。
stringbuilder.append()を使用します。
非常に単純で、xmldocument.load(strinbuilderオブジェクトをパラメーターとして)を実行できます。
おそらく、appendパラメータ内でstring.concatを使用していますが、これは非常に簡単な方法です。