将对象序列化为XML
我有一个C#类,我已经inheritance。 我已经成功“build立”了这个对象。 但是我需要将对象序列化为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表示forms?
您必须使用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 } }
我修改我的返回一个string,而不是使用像下面的refvariables。
public static string Serialize<T>(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保存函数。
/// <summary> /// Saves to an xml file /// </summary> /// <param name="FileName">File path of the new xml file</param> 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(); } }
要从保存的文件中创build对象,请添加以下函数,并用要创build的对象typesreplace[ObjectType]。
/// <summary> /// Load an object from an xml file /// </summary> /// <param name="FileName">Xml file name</param> /// <returns>The object created from the xml file</returns> 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]; } }
您可以使用下面的函数从任何对象获取序列化的XML。
public static bool Serialize<T>(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 System.IO; using System.Xml; using System.Xml.Serialization; namespace MyProj.Extensions { public static class XmlExtension { public static string Serialize<T>(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
),你可以在扩展方法中replaceT
参数,例如。
public static string Serialize(this Foo value){...}
要序列化一个对象,请执行:
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(); } }
我之前使用过这个代码。 但现实表明,这个解决scheme有点问题。 通常,大多数程序员只是在载入时序列化保存和反序列化设置。 这是一个乐观的情况。 一旦序列化失败,由于某种原因文件被部分写入,XML文件不完整并且是无效的。 因此,XML反序列化不起作用,您的应用程序可能会在开始时崩溃。 如果文件不是很大,我build议首先将对象序列化到MemoryStream
然后将stream写入文件。 如果有一些复杂的自定义序列化,这种情况特别重要。 你永远不能testing所有的情况。
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提供的加载function很好。
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(); } }
这比调用类的ToString
方法稍微复杂一些,但不是很多。
这里有一个简单的插入函数,可以用来序列化任何types的对象。 它返回一个包含序列化XML内容的string:
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; } }
这里是一个很好的教程如何做到这一点
你应该基本上使用System.Xml.Serialization.XmlSerializer
类来做到这一点。
string FilePath = ConfigurationReader.FileLocation; //Getting path value from web.config XmlSerializer serializer = new XmlSerializer(typeof(Devices)); //typeof(object) MemoryStream memStream = new MemoryStream(); serializer.Serialize(memStream, lstDevices);//lstdevices : I take result as a list. FileStream file = new FileStream(folderName + "\\Data.xml", FileMode.Create, FileAccess.ReadWrite); //foldername:Specify the path to store the xml file memStream.WriteTo(file); file.Close();
您可以创build结果并将其作为xml文件存储在所需的位置。
或者你可以添加这个方法到你的对象:
public void Save(string filename) { var ser = new XmlSerializer(this.GetType()); using (var stream = new FileStream(filename, FileMode.Create)) ser.Serialize(stream, this); }
我的工作代码。 返回utf8 xml启用空名称空间。
// override StringWriter public class Utf8StringWriter : StringWriter { public override Encoding Encoding => Encoding.UTF8; } private string GenerateXmlResponse(Object obj) { Type t = obj.GetType(); var xml = ""; using (StringWriter sww = new Utf8StringWriter()) { using (XmlWriter writer = XmlWriter.Create(sww)) { var ns = new XmlSerializerNamespaces(); // add empty namespace ns.Add("", ""); XmlSerializer xsSubmit = new XmlSerializer(t); xsSubmit.Serialize(writer, obj, ns); xml = sww.ToString(); // Your XML } } return xml; }
示例返回响应Yandex api付款Aviso url:
<?xml version="1.0" encoding="utf-8"?><paymentAvisoResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" performedDatetime="2017-09-01T16:22:08.9747654+07:00" code="0" shopId="54321" invoiceId="12345" orderSumAmount="10643" />