Come posso creare XML in C #?


438

Come posso generare un XML valido in C #?

Risposte:


510

Dipende dallo scenario. XmlSerializerè certamente un modo e ha il vantaggio di mappare direttamente su un modello a oggetti. In .NET 3.5, XDocumentecc. Sono anche molto amichevoli. Se la dimensione è molto grande, allora XmlWriterè tuo amico.

Per un XDocumentesempio:

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

O lo stesso con 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);

Se stai scrivendo un grande flusso di dati, uno qualsiasi degli approcci DOM (come XmlDocument/ XDocument, ecc.) Occuperà rapidamente molta memoria. Quindi, se stai scrivendo un file XML da 100 MB da CSV , potresti prendere in considerazione XmlWriter; questo è più primitivo (un firehose write-once), ma molto efficiente (immagina un grande loop qui):

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

Infine, tramite 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);

Questo è un bel modello per mappare le classi, ecc .; tuttavia, potrebbe essere eccessivo se stai facendo qualcosa di semplice (o se l'XML desiderato non ha una correlazione diretta con il modello a oggetti). Un altro problema XmlSerializerè che non gli piace serializzare tipi immutabili: tutto deve avere un getter e setter pubblici (a meno che tu non faccia tutto da solo implementando IXmlSerializable, nel qual caso non hai guadagnato molto usando XmlSerializer).


10
Non dimenticare XStreamingElement, msdn.microsoft.com/en-us/library/... . :)
Todd White,

1
Per l'esempio di XmlWriter è importante notare che è necessario chiudere il writer alla fine affinché funzioni correttamente: writer.Close () è necessario dopo il writer.WriteEndElement ().
Marko

È vero ciò che dice @Marko: è importante chiudere correttamente lo scrittore. C'è anche un altro modo per farlo, invece di chiamare writer.Close () direttamente. Puoi racchiudere la chiamata a Create () in un'istruzione using in questo modo: using (XmlWriter writer = XmlWriter.Create (Console.Out)) {writer.WriteStartElement ("Foo"); ecc} C'è un altro esempio (un po 'più migliorato) di XmlWriter qui: dotnetperls.com/xmlwriter
Morten

@Morten Sicuramente se XmlWriter implementa IDisposable, l'utilizzo dell'istruzione è l'opzione migliore.
Marko,

Il buon vecchio XMLDocument ha tutto. Semplice, chiaro e chiaro se si sta creando un documento XML.
FrenkyB,

60

La cosa migliore che ho provato è LINQ to XSD (che è sconosciuto alla maggior parte degli sviluppatori). Gli dai uno schema XSD e genera un modello a oggetti fortemente tipizzato completo perfettamente mappato (basato su LINQ to XML) per te in background, che è davvero facile da lavorare - e aggiorna e convalida il tuo modello a oggetti e XML in tempo reale. Mentre è ancora "Anteprima", non ho riscontrato alcun bug con esso.

Se hai uno schema XSD simile a questo:

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

Quindi puoi semplicemente creare XML in questo modo:

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

O semplicemente carica un XML da un file come questo:

RootElement rootElement = RootElement.Load(filePath);

O salvalo in questo modo:

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

rootElement.Untyped restituisce inoltre l'elemento in forma di XElement (da LINQ a XML).


sembra che questo codice non funzioni codice. quando avrò intenzione di fare in questo modo non ci sarà nessuna applicazione di Salva fucntionRootElement
DanilGholtsman

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 è il modo più veloce per scrivere un buon XML. XDocument, XMLDocument e alcuni altri funzionano bene, ma non sono ottimizzati per la scrittura di XML. Se vuoi scrivere l'XML il più velocemente possibile, dovresti assolutamente usare XmlWriter.


6
Cioè, se vuoi che il computer scriva l'XML il più velocemente possibile. Se tu, lo sviluppatore, vuoi creare XML nel modo più semplice e naturale, XmlWriter non è probabilmente la soluzione!
sjy


4

Penso che questa risorsa dovrebbe essere sufficiente per un moderato salvataggio / caricamento XML: lettura / scrittura XML tramite C # .

Il mio compito era quello di memorizzare la notazione musicale. Scelgo XML, perché suppongo che .NET abbia maturato abbastanza da consentire una soluzione semplice per l'attività. Avevo ragione :)

Questo è il mio prototipo del file della canzone:

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

Questo può essere risolto abbastanza facilmente:

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

 }

Per caricare il file:

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

Per semplicità, utilizzo semplicemente le classi XmlDocument / XmlNode / XmlAttribute e il DOM XmlDocument presenti in System.XML.

Genera l'XML per me, ho solo bisogno di collegare alcuni elementi insieme.

Tuttavia, su cose più grandi, utilizzo la serializzazione XML.


1

Per casi semplici, suggerirei anche di guardare XmlOutput un'interfaccia fluida per la creazione di Xml.

XmlOutput è ottimo per la semplice creazione di XML con codice leggibile e gestibile, generando al contempo un XML valido. Il post originale ha alcuni grandi esempi.


-3

Come sopra.

Uso stringbuilder.append ().

Molto semplice, e quindi puoi fare xmldocument.load (oggetto strinbuilder come parametro).

Probabilmente ti ritroverai a utilizzare string.concat all'interno del parametro append, ma questo è un approccio molto semplice.


11
Tranne quando si dimentica di codificare qualcosa in modo corretto e scrivere XML illegale.
Robert Paulson,

3
Questa risposta è stata assolutamente sbattuta, ma sulla base di questa domanda ho dato un'occhiata a una delle mie implementazioni in cui ho creato XML. Per il mio particolare progetto ho scoperto costantemente che la costruzione tramite StringBuilder ha comportato tempi di elaborazione del 10% più rapidi rispetto all'utilizzo di XDocument / XmlWriter. Ma mi sento a mio agio con XML, e questo è per il mio progetto particolare. (Per riferimento, le dimensioni XML finali sono circa 3,4 MB, con oltre 8000 righe.)
James Skemp

2
Sarei curioso di sapere se hai misurato il compromesso tra le prestazioni delle applicazioni (stiamo parlando di miglioramenti di millisecondi qui?) E la manutenzione delle applicazioni (i tuoi ingegneri devono familiarizzare con il codice per un'ora prima di apportare modifiche ora?)
Dan Esparza,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.