Come posso generare un XML valido in C #?
Come posso generare un XML valido in C #?
Risposte:
Dipende dallo scenario. XmlSerializer
è certamente un modo e ha il vantaggio di mappare direttamente su un modello a oggetti. In .NET 3.5, XDocument
ecc. Sono anche molto amichevoli. Se la dimensione è molto grande, allora XmlWriter
è tuo amico.
Per un XDocument
esempio:
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
).
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).
RootElement
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.
In passato ho creato il mio schema XML, quindi ho usato uno strumento per generare classi C # che verranno serializzate su quello schema. Lo strumento di definizione dello schema XML è un esempio
http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx
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);
}
}
}
}
}
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.
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.