Después de consultar especialistas en el tema, programadores de varias ramas y profesores dimos con la solución a la cuestión y la compartimos en este post.
Solución:
Depende del escenario. XmlSerializer
es ciertamente una forma y tiene la ventaja de mapear directamente a un modelo de objetos. En .NET 3.5, XDocument
, etc. también son muy amables. 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ás escribiendo un largo flujo de datos, entonces 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, podría considerar XmlWriter
; esto es más primitivo (una manguera de fuego 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 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 con XmlSerializer
es que no le gusta serializar tipos inmutables: todo debe tener un captador público y setter (a menos que lo haga todo usted mismo implementando IXmlSerializable
en cuyo caso no ha ganado mucho usando XmlSerializer
).
Sin duda, lo mejor que he probado es LINQ to XSD (que es desconocido para la mayoría de los desarrolladores). Le asigna un esquema XSD y genera un modelo de objetos fuertemente tipado completo perfectamente mapeado (basado en LINQ to XML) para usted en segundo plano, con el que es realmente fácil trabajar, y actualiza y valida su modelo de objetos 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í:
Entonces simplemente puede construir XML como este:
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 guardarlo 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).
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)
)
);