2008-11-12 9 views

Antwort

473

Es hängt vom Szenario ab. XmlSerializer ist sicherlich eine Möglichkeit und hat den Vorteil, direkt auf ein Objektmodell abzubilden. In .NET 3.5, XDocument usw. sind auch sehr freundlich. Wenn die Größe sehr groß ist, dann ist XmlWriter dein Freund.

Für ein XDocument Beispiel:

Console.WriteLine(
    new XElement("Foo", 
     new XAttribute("Bar", "some & value"), 
     new XElement("Nested", "data"))); 

Oder das gleiche mit 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); 

Wenn Sie einen großen Datenstrom, dann eine der DOM Schreiben Ansätze (wie XmlDocument/XDocument usw.) wird schnell viel Speicher benötigen. Wenn Sie also eine 100   MB-XML-Datei von CSV schreiben, könnten Sie XmlWriter betrachten; dies ist primitiver (ein einmal Feuerwehrschlauch), aber sehr effizient (eine große Schleife vorstellen, hier):

XmlWriter writer = XmlWriter.Create(Console.Out); 
writer.WriteStartElement("Foo"); 
writer.WriteAttributeString("Bar", "Some & value"); 
writer.WriteElementString("Nested", "data"); 
writer.WriteEndElement(); 

schließlich über 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); 

Dies ist ein schönes Modell für die Zuordnung zu Klassen usw .; Es ist jedoch möglicherweise zu viel Aufwand, wenn Sie etwas Einfaches tun (oder wenn das gewünschte XML nicht direkt mit dem Objektmodell korreliert). Ein weiteres Problem mit XmlSerializer ist, dass es nicht mag unveränderliche Typen serialisieren: alles muss eine öffentliche Getter und Setter (wenn Sie alles selbst durch die Implementierung IXmlSerializable machen, in diesem Fall haben Sie nicht viel gewonnen mit XmlSerializer) .

+9

Vergessen Sie nicht Xstreaming Element, http://msdn.microsoft.com/en-us/library/system.xml.linq.xstreamingelement.aspx. :) –

+1

Für XmlWriter Beispiel ist es wichtig zu beachten, dass Sie den Schreiber am Ende schließen müssen, damit es ordnungsgemäß funktioniert - writer.Close() wird nach dem writer.WriteEndElement() benötigt. – Marko

20

Ich würde XLINQ geben (lesen: LINQ zu XML) ein Versuch. Es ist einfach, intuitiv und einfach zu bearbeiten.

Probe: Reading and Writing XML using XLinq

+1

Ich fand diesen Fund wirklich nützlich, danke Tschad.Zwar gibt es Zeiten, in denen die Serialisierung die richtige Antwort ist, aber es gibt viele Szenarien, in denen komplexe XML-Generierung im Code die richtige Antwort ist. Es ist eine Schande, dass C# nicht die gleichen Inline-Xml-Fähigkeiten wie VB.net hat. Danke noch einmal. – Russell

+1

Die Verwendung von XElement von System.Xml.Linq zum Generieren der XML ist sehr praktisch – Jemsworld

8

XmlWriter ist der schnellste Weg, um gute XML zu schreiben. XDocument, XMLDocument und einige andere funktionieren auch gut, sind aber nicht für das Schreiben von XML optimiert. Wenn Sie das XML so schnell wie möglich schreiben möchten, sollten Sie unbedingt XmlWriter verwenden.

+5

Das heißt, wenn Sie wollen, dass der * Computer * das XML so schnell wie möglich schreibt. Wenn Sie, der Entwickler, XML auf die einfachste und natürlichste Weise erstellen möchten, ist XmlWriter wahrscheinlich nicht die Lösung! – sjy

1

Für einfache Dinge verwende ich einfach die XmlDocument/XmlNode/XmlAttribute-Klassen und XmlDocument DOM in System.XML gefunden.

Es generiert das XML für mich, ich muss nur ein paar Elemente miteinander verknüpfen.

Bei größeren Dingen verwende ich XML-Serialisierung.

1

Für einfache Fälle würde ich auch vorschlagen, XmlOutput eine fließende Oberfläche für den Aufbau von Xml.

XmlOutput ist ideal für einfache Xml-Erstellung mit lesbarem und wartbarem Code, während gültige Xml generiert. Die orginal post hat einige großartige Beispiele.

-4

Wie oben.

Ich benutze stringbuilder.append().

Sehr einfach, und Sie können dann xmldocument.load (strinbuilder Objekt als Parameter) tun.

Sie werden wahrscheinlich innerhalb des append-Parameters string.concat verwenden, aber dies ist ein sehr einfacher Ansatz.

+10

Außer wenn Sie vergessen, etwas richtig zu kodieren und illegales Xml zu schreiben. –

+3

Diese Antwort wurde absolut geknackt, aber basierend auf dieser Frage habe ich mir eine meiner eigenen Implementierungen angeschaut, in denen ich XML erstelle. Für mein spezielles Projekt fand ich heraus, dass das Erstellen über StringBuilder zu Verarbeitungszeiten von 10% schneller führte als mit XDocument/XmlWriter. Aber ich fühle mich wohl mit XML, und das ist für mein spezielles Projekt. (Als Referenz sind die endgültigen XML-Größen etwa 3,4 MB, mit über 8000 Zeilen.) –

+2

Ich würde gerne wissen, ob Sie den Kompromiss zwischen Anwendungsleistung (sprechen wir hier Millisekunden-Verbesserungen?) Und Anwendungswartung (machen Sie Ihre Ingenieure müssen sich eine Stunde lang mit dem Code vertraut machen, bevor sie jetzt Änderungen vornehmen?) –

57

Das Beste, was ich ausprobiert habe, ist LINQ to XSD (was den meisten Entwicklern unbekannt ist). Sie geben ihm ein XSD-Schema und generieren für Sie im Hintergrund ein perfekt gemapptes vollständiges, stark typisiertes Objektmodell (basierend auf LINQ to XML), mit dem Sie sehr einfach arbeiten können - und es aktualisiert und validiert Ihr Objektmodell und XML in Echtzeit. Während es immer noch "Vorschau" ist, habe ich keine Fehler mit ihm festgestellt.

Wenn Sie ein XSD-Schema haben, die wie folgt aussieht:

<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> 

Dann können Sie einfach XML wie folgt aufbauen:

RootElement rootElement = new RootElement; 
rootElement.Element1 = "Element1"; 
rootElement.Element2 = "Element2"; 
rootElement.Attribute1 = 5; 
rootElement.Attribute2 = true; 

Oder einfach eine XML aus einer Datei wie folgt laden:

Oder speichern Sie es wie folgt:

rootElement.Save(string); 
rootElement.Save(textWriter); 
rootElement.Save(xmlWriter); 

rootElement.Untyped liefert auch das Element in Form eines XElement (von LINQ nach XML).

+4

Beachten Sie, dass dieses Projekt ab sofort ziemlich nah am Tod ist. –

+1

@James: '[Zitat-benötigt]' –

+7

@Robert Harvey: Überprüfen Sie das Datum meines Kommentars. Drei Tage später begannen die Commits/Fixes ins Rollen zu kommen. Ehrlich gesagt bin ich froh, dass sich das Projekt gedreht hat, da ich es jetzt als machbare Option ansehen kann. –

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

Ich denke, diese Ressource sollte für eine moderate XML speichern/laden: Read/Write XML using C#.

Meine Aufgabe war es, Notation zu speichern. Ich wähle XML, weil ich denke, dass .NET genug gereift ist, um eine einfache Lösung für die Aufgabe zu ermöglichen. Ich hatte recht :)

Das ist mein Song-Datei Prototyp:

<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> 

, die ganz leicht gelöst werden können:

Für Save to File:

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

} 

Für Last-Datei:

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

} 
} 
Verwandte Themen