我有一个我继承的C#类.我已成功"建立"了这个对象.但我需要将对象序列化为XML.有一个简单的方法吗?
看起来这个类已经设置为序列化,但我不知道如何获得XML表示.我的类定义如下所示:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.domain.com/test")] [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.domain.com/test", IsNullable = false)] public partial class MyObject { ... }
这是我认为我可以做的,但它不起作用:
MyObject o = new MyObject(); // Set o properties string xml = o.ToString();
如何获取此对象的XML表示?
您必须使用XmlSerializer进行XML序列化.以下是一个示例代码段.
XmlSerializer xsSubmit = new XmlSerializer(typeof(MyObject)); var subReq = new MyObject(); var xml = ""; using(var sww = new StringWriter()) { using(XmlWriter writer = XmlWriter.Create(sww)) { xsSubmit.Serialize(writer, subReq); xml = sww.ToString(); // Your XML } }
我修改了我的返回字符串,而不是像下面那样使用ref变量.
public static string Serialize(this T value) { if (value == null) { return string.Empty; } try { var xmlserializer = new XmlSerializer(typeof(T)); var stringWriter = new StringWriter(); using (var writer = XmlWriter.Create(stringWriter)) { xmlserializer.Serialize(writer, value); return stringWriter.ToString(); } } catch (Exception ex) { throw new Exception("An error occurred", ex); } }
它的用法如下:
var xmlString = obj.Serialize();
可以使用System.Xml命名空间将以下函数复制到任何对象以添加XML保存功能.
////// Saves to an xml file /// /// File path of the new xml file public void Save(string FileName) { using (var writer = new System.IO.StreamWriter(FileName)) { var serializer = new XmlSerializer(this.GetType()); serializer.Serialize(writer, this); writer.Flush(); } }
要从保存的文件创建对象,请添加以下函数,并将[ObjectType]替换为要创建的对象类型.
////// Load an object from an xml file /// /// Xml file name ///The object created from the xml file public static [ObjectType] Load(string FileName) { using (var stream = System.IO.File.OpenRead(FileName)) { var serializer = new XmlSerializer(typeof([ObjectType])); return serializer.Deserialize(stream) as [ObjectType]; } }
扩展类:
using System.IO; using System.Xml; using System.Xml.Serialization; namespace MyProj.Extensions { public static class XmlExtension { public static string Serialize(this T value) { if (value == null) return string.Empty; var xmlSerializer = new XmlSerializer(typeof(T)); using (var stringWriter = new StringWriter()) { using (var xmlWriter = XmlWriter.Create(stringWriter,new XmlWriterSettings{Indent = true})) { xmlSerializer.Serialize(xmlWriter, value); return stringWriter.ToString(); } } } } }
用法:
Foo foo = new Foo{MyProperty="I have been serialized"}; string xml = foo.Serialize();
只是引用该命名空间牵着你的扩展方法在文件中,你想在使用它,它会工作(在我的例子那就是:using MyProj.Extensions;
)
请注意,如果要使扩展方法仅针对特定类(例如,Foo
),则可以替换T
扩展方法中的参数,例如.
public static string Serialize(this Foo value){...}
您可以使用下面的函数从任何对象获取序列化的XML.
public static bool Serialize(T value, ref string serializeXml) { if (value == null) { return false; } try { XmlSerializer xmlserializer = new XmlSerializer(typeof(T)); StringWriter stringWriter = new StringWriter(); XmlWriter writer = XmlWriter.Create(stringWriter); xmlserializer.Serialize(writer, value); serializeXml = stringWriter.ToString(); writer.Close(); return true; } catch (Exception ex) { return false; } }
您可以从客户端调用此方法.
要序列化对象,请执行以下操作:
using (StreamWriter myWriter = new StreamWriter(path, false)) { XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type)); mySerializer.Serialize(myWriter, objectToSerialize); }
还要记住,要使XmlSerializer工作,您需要一个无参数构造函数.
我将从Ben Gripka的副本答案开始:
public void Save(string FileName) { using (var writer = new System.IO.StreamWriter(FileName)) { var serializer = new XmlSerializer(this.GetType()); serializer.Serialize(writer, this); writer.Flush(); } }
我之前使用过这段代码.但现实表明,这个解决方案有点问题.通常,大多数程序员只是在加载时序列化设置保存和反序列化设置.这是一个乐观的情景.一旦序列化失败,由于某种原因,文件被部分写入,XML文件不完整且无效.因此,XML反序列化不起作用,您的应用程序可能会在启动时崩溃.如果文件不是很大,我建议首先序列化对象MemoryStream
然后将流写入文件.如果存在一些复杂的自定义序列化,则此情况尤为重要.你永远无法测试所有案例.
public void Save(string fileName) { //first serialize the object to memory stream, //in case of exception, the original file is not corrupted using (MemoryStream ms = new MemoryStream()) { var writer = new System.IO.StreamWriter(ms); var serializer = new XmlSerializer(this.GetType()); serializer.Serialize(writer, this); writer.Flush(); //if the serialization succeed, rewrite the file. File.WriteAllBytes(fileName, ms.ToArray()); } }
现实世界场景中的反序列化应该与损坏的序列化文件一起计算,它会在某个时间发生.Ben Gripka提供的加载功能很好.
public static [ObjectType] Load(string fileName) { using (var stream = System.IO.File.OpenRead(fileName)) { var serializer = new XmlSerializer(typeof([ObjectType])); return serializer.Deserialize(stream) as [ObjectType]; } }
它可以被一些恢复方案包裹起来.它适用于设置文件或其他可在出现问题时删除的文件.
public static [ObjectType] LoadWithRecovery(string fileName) { try { return Load(fileName); } catch(Excetion) { File.Delete(fileName); //delete corrupted settings file return GetFactorySettings(); } }
以上所有建议的答案都是正确的。这是最简单的版本:
private string Serialize(Object o) { using (var writer = new StringWriter()) { new XmlSerializer(o.GetType()).Serialize(writer, o); return writer.ToString(); } }
它比调用ToString
类的方法要复杂一点,但并不多.
这是一个简单的drop-in函数,可用于序列化任何类型的对象.它返回一个包含序列化XML内容的字符串:
public string SerializeObject(object obj) { System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { serializer.Serialize(ms, obj); ms.Position = 0; xmlDoc.Load(ms); return xmlDoc.InnerXml; } }