¿Cómo puedo generar XML válido en C #?
¿Cómo puedo generar XML válido en C #?
Respuestas:
Depende del escenario. XmlSerializer
Sin duda es una forma y tiene la ventaja de mapear directamente a un modelo de objeto. En .NET 3.5, XDocument
etc. también son muy amigables. Si el tamaño es muy grande, entonces XmlWriter
es tu amigo.
Por un XDocument
ejemplo:
Console.WriteLine(
new XElement("Foo",
new XAttribute("Bar", "some & value"),
new XElement("Nested", "data")));
O lo mismo 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);
Si está escribiendo una gran secuencia de datos, cualquiera de los enfoques DOM (como XmlDocument
/ XDocument
, etc.) ocupará rápidamente mucha memoria. Entonces, si está escribiendo un archivo XML de 100 MB desde CSV , puede considerar XmlWriter
; Esto es más primitivo (una manguera de incendios de escritura única), pero muy eficiente (imagine un gran bucle aquí):
XmlWriter writer = XmlWriter.Create(Console.Out);
writer.WriteStartElement("Foo");
writer.WriteAttributeString("Bar", "Some & value");
writer.WriteElementString("Nested", "data");
writer.WriteEndElement();
Finalmente, a través de 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);
Este es un buen modelo para mapear a clases, etc .; sin embargo, podría ser excesivo si está haciendo algo simple (o si el XML deseado realmente no tiene una correlación directa con el modelo de objetos). Otro problema XmlSerializer
es que no le gusta serializar los tipos inmutables: todo debe tener un captador y configurador público (a menos que lo haga todo usted mismo mediante la implementación IXmlSerializable
, en cuyo caso no ha ganado mucho al usarlo XmlSerializer
).
Lo mejor que he probado es LINQ to XSD (que la mayoría de los desarrolladores desconocen). Le da un esquema XSD y genera un modelo de objeto completo fuertemente tipado perfectamente mapeado (basado en LINQ to XML) para usted en segundo plano, que es realmente fácil de trabajar, y actualiza y valida su modelo de objeto y XML en tiempo real. Si bien todavía es "Vista previa", no he encontrado ningún error con él.
Si tiene un esquema XSD que se ve así:
<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>
Entonces puedes simplemente crear XML de esta manera:
RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootElement.Element2 = "Element2";
rootElement.Attribute1 = 5;
rootElement.Attribute2 = true;
O simplemente cargue un XML desde un archivo como este:
RootElement rootElement = RootElement.Load(filePath);
O guárdelo así:
rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);
rootElement.Untyped
también produce el elemento en forma de XElement (de LINQ a XML).
RootElement
XmlWriter es la forma más rápida de escribir un buen XML. XDocument, XMLDocument y algunos otros también funcionan bien, pero no están optimizados para escribir XML. Si desea escribir el XML lo más rápido posible, definitivamente debe usar XmlWriter.
En el pasado, creé mi esquema XML, luego utilicé una herramienta para generar clases de C # que se serializarán en ese esquema. La herramienta de definición de esquemas XML es un ejemplo
http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx
Creo que este recurso debería ser suficiente para guardar / cargar XML moderadamente: leer / escribir XML usando C # .
Mi tarea era almacenar la notación musical. Elijo XML, porque supongo que .NET ha madurado lo suficiente como para permitir una solución fácil para la tarea. Yo tenía razón :)
Este es mi prototipo de archivo de canción:
<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>
Eso se puede resolver con bastante facilidad:
Para guardar en archivo:
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();
}
}
Para cargar archivo:
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);
}
}
}
}
}
Para casos simples, también sugeriría buscar en XmlOutput una interfaz fluida para construir Xml.
XmlOutput es ideal para la creación simple de Xml con código legible y mantenible, mientras genera Xml válido. La publicación original tiene algunos excelentes ejemplos.
Como anteriormente.
Yo uso stringbuilder.append ().
Muy sencillo, y luego puede hacer xmldocument.load (objeto strinbuilder como parámetro).
Probablemente se encontrará utilizando string.concat dentro del parámetro append, pero este es un enfoque muy sencillo.