C#でXMLを作成するにはどうすればよいですか?


438

C#で有効なXMLを生成するにはどうすればよいですか?

回答:


510

シナリオによって異なります。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)。


10
XStreamingElement、msdn.microsoft.com / en-us / library /…を忘れないでください。:)
Todd White、

1
XmlWriterの例では、正しく機能するために最後にライターを閉じる必要があることに注意することが重要です。writer.Close()はwriter.WriteEndElement()の後に必要です。
Marko

@Markoの言うとおりです。ライターを適切に閉じることが重要です。writer.Close()を直接呼び出す代わりに、これを行う別の方法もあります。Create()の呼び出しは、次のようなusingステートメントでラップできます。using(XmlWriter writer = XmlWriter.Create(Console.Out)){writer.WriteStartElement( "Foo"); ここにXmlWriterの別の(もう少し拡張された)例があります:dotnetperls.com/xmlwriter
Morten

@Morten XmlWriterがIDisposableを実装している場合は、ステートメントを使用するのが最善のオプションです。
マルコ

古き良きXMLDocumentはそれをすべて持っています。XMLドキュメントを作成する場合は、単純明快です。
-FrenkyB

60

私が試した中で最も良いことは、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
DanilGholtsman 2014年

24
new XElement("Foo",
       from s in nameValuePairList
       select
             new XElement("Bar",
                  new XAttribute("SomeAttr", "SomeAttrValue"),
                          new XElement("Name", s.Name),
                          new XElement("Value", s.Value)
                         )
            );

10

XmlWriterは、優れたXMLを作成する最速の方法です。XDocument、XMLDocumentなども同様に機能しますが、XMLの書き込み用に最適化されていません。XMLを可能な限り高速に記述したい場合は、必ずXmlWriterを使用する必要があります。


6
つまり、コンピュータで XMLを可能な限り高速に書き込みたい場合です。開発者が最も簡単で自然な方法でXMLを作成したい場合、XmlWriterはおそらくソリューションではありません!
sjy 2014


4

このリソースは、適度な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);
            }
    }
}

}
}

1

簡単なことには、System.XMLにあるXmlDocument / XmlNode / XmlAttributeクラスとXmlDocument DOMを使用するだけです。

それは私のためにXMLを生成します、私はいくつかのアイテムを一緒にリンクする必要があるだけです。

ただし、より大きなものでは、XMLシリアル化を使用します。


1

単純なケースでは、XmlOutputを見て、Xml を作成するための流暢なインターフェイスも検討することをお勧めします。

XmlOutputは、有効なXmlを生成しながら、読み取り可能で保守可能なコードを使用した単純なXml作成に最適です。元の投稿にはいくつかの素晴らしい例があります。


-3

上記のように。

stringbuilder.append()を使用します。

非常に単純で、xmldocument.load(strinbuilderオブジェクトをパラメーターとして)を実行できます。

おそらく、appendパラメータ内でstring.concatを使用していますが、これは非常に簡単な方法です。


11
何かを適切にエンコードするのを忘れて、違法なXmlを書く場合を除いて。
ロバートポールソン、

3
この答えは完全に非難されましたが、この質問に基づいて、私はXMLを構築する自分の実装の1つを調べました。私の特定のプロジェクトでは、StringBuilderを介して構築すると、XDocument / XmlWriterを使用するよりも処理時間が10%速くなることが一貫してわかりました。しかし、私はXMLに慣れていると感じています。それは、私の特定のプロジェクトのためのものです。(参考までに、最終的なXMLサイズは約3.4 MB、8000行以上です。)
James Skemp

2
あなたは、アプリケーションのパフォーマンス(?ここでは、ミリ秒の改善を話している)と、アプリケーションの保守(?あなたのエンジニアは今変更を行う前に、時間コードに慣れる必要があります)の間のトレードオフを測定した場合、私は知りたいだろう
ダンエスパルサ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.