2008-11-12 49 views

回答

473

這取決於場景。 XmlSerializer肯定是一種方法,並具有直接映射到對象模型的優點。在.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的MB文件,您可能會考慮XmlWriter;這是最原始的(單次寫入流水),但非常有效的(想象這裏一個大循環):

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與對象模型沒有真正的直接關係),它可能會過度殺傷。與XmlSerializer另一個問題是,它不喜歡一成不變的序列化類型:一切都必須有一個公共的getter 二傳手(除非你通過實施IXmlSerializable,做這一切你自己在這種情況下,你還沒有使用XmlSerializer獲得了很多) 。

+9

不要忘記XStreaming元素,http://msdn.microsoft.com/en-us/library/system.xml.linq.xstreamingelement.aspx。 :) – 2008-11-12 16:12:49

+1

對於XmlWriter示例,需要注意的是,爲了正確工作,需要關閉寫入程序 - 在writer.WriteEndElement()之後需要writer.Close()。 – Marko 2015-03-03 19:39:34

20

我會給XLINQ(閱讀:LINQ to XML)一試。它很容易,直觀並且易於編輯。

樣品:Reading and Writing XML using XLinq

+1

我發現這個發現非常有用,謝謝乍得。雖然有時候序列化是正確的答案,但有很多情況下,代碼中複雜的xml代是正確的答案。這是一個恥辱C#不具有與VB.net相同的內聯Xml能力。再次感謝。 – Russell 2009-09-30 06:15:23

+1

使用System.Xml.Linq的XElement生成xml非常方便 – Jemsworld 2012-05-26 23:29:30

8

的XmlWriter是編寫好的XML的最快方式。 XDocument,XMLDocument和其他一些工作也很好,但沒有針對編寫XML進行優化。如果你想盡可能快地寫XML,你應該使用XmlWriter。

+5

也就是說,如果您希望*計算機*儘可能快地寫入XML。如果您是開發人員,想要以最簡單和最自然的方式創建XML,那麼XmlWriter可能不是解決方案! – sjy 2014-02-24 08:01:56

1

對於簡單的事情,我只使用System.XML中的XmlDocument/XmlNode/XmlAttribute類和XmlDocument DOM。

它爲我生成XML,我只需要將幾個項目鏈接在一起。

但是,在更大的事情上,我使用XML序列化。

1

對於簡單的情況,我也建議看看XmlOutput流利的接口來構建Xml。

XmlOutput非常適合用可讀和可維護的代碼創建簡單的Xml,同時生成有效的Xml。 orginal post有一些很好的例子。

-4

如上。

我使用stringbuilder.append()。

非常簡單,然後你可以做xmldocument.load(作爲參數的strictbuilder對象)。

您可能會發現自己在append參數中使用string.concat,但這是一個非常簡單的方法。

57

我試過的最好的東西是LINQ to XSD(這對大多數開發者來說是未知的)。你給它一個XSD Schema,它會在後臺爲你生成一個完美映射的完整強類型對象模型(基於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)。

22
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) 
         ) 
      ); 
3

我認爲這個資源應該足夠適合XML保存/加載:Read/Write XML using C#

我的任務是存儲音樂符號。我選擇XML,因爲我猜.NET已經足夠成熟,可以輕鬆解決任務。我是正確的:)

這是我的歌曲文件的原型:

<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); 
      } 
    } 
} 

} 
}