我有一个我继承的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表示?
答案 0 :(得分:429)
您必须使用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
}
}
答案 1 :(得分:102)
我修改了我的返回字符串,而不是像下面那样使用ref变量。
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();
答案 2 :(得分:37)
可以使用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();
}
}
要从保存的文件创建对象,请添加以下函数,并将[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];
}
}
答案 3 :(得分:28)
您可以使用下面的函数从任何对象获取序列化的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;
}
}
您可以从客户端拨打此电话。
答案 4 :(得分:28)
扩展类:
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
),则可以替换扩展方法中的T
参数,例如。
public static string Serialize(this Foo value){...}
答案 5 :(得分:17)
要序列化对象,请执行以下操作:
using (StreamWriter myWriter = new StreamWriter(path, false))
{
XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
mySerializer.Serialize(myWriter, objectToSerialize);
}
还要记住,要使XmlSerializer工作,您需要一个无参数构造函数。
答案 6 :(得分:16)
我将从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();
}
}
答案 7 :(得分:6)
比调用类的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;
}
}
答案 8 :(得分:5)
基于上述解决方案,这里有一个扩展类,您可以使用该扩展类对任何对象进行序列化和反序列化。其他XML属性归您决定。
只需像这样使用它:
string s = new MyObject().Serialize(); // to serialize into a string
MyObject b = s.Deserialize<MyObject>();// deserialize from a string
internal static class Extensions
{
public static T Deserialize<T>(this string value)
{
var xmlSerializer = new XmlSerializer(typeof(T));
return (T)xmlSerializer.Deserialize(new StringReader(value));
}
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();
}
}
}
}
答案 9 :(得分:3)
上面所有推荐的答案都是正确的。这只是最简单的版本:
private string Serialize(Object o)
{
using (var writer = new StringWriter())
{
new XmlSerializer(o.GetType()).Serialize(writer, o);
return writer.ToString();
}
}
答案 10 :(得分:3)
Here is a good tutorial on how to do this
您基本上应该使用System.Xml.Serialization.XmlSerializer
类来执行此操作。
答案 11 :(得分:2)
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();
您可以在所需位置创建结果并将其存储为xml文件。
答案 12 :(得分:2)
我的工作代码。返回 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 payment 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" />
答案 13 :(得分:1)
我有一种使用C#将对象序列化为XML的简单方法,它工作得很好并且具有很高的可重用性。我知道这是一个较旧的主题,但我想发布此主题,因为有人可能认为这对他们有帮助。
这是我调用方法的方式:
var objectToSerialize = new MyObject();
var xmlString = objectToSerialize.ToXmlString();
这是完成工作的班级:
注意:由于这些是扩展方法,因此需要在静态类中。
using System.IO;
using System.Xml.Serialization;
public static class XmlTools
{
public static string ToXmlString<T>(this T input)
{
using (var writer = new StringWriter())
{
input.ToXml(writer);
return writer.ToString();
}
}
private static void ToXml<T>(this T objectToSerialize, StringWriter writer)
{
new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
}
}
答案 14 :(得分:0)
或者您可以将此方法添加到对象中:
public void Save(string filename)
{
var ser = new XmlSerializer(this.GetType());
using (var stream = new FileStream(filename, FileMode.Create))
ser.Serialize(stream, this);
}
答案 15 :(得分:0)
public string ObjectToXML(object input)
{
try
{
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(input.GetType());
serializer.Serialize(stringwriter, input);
return stringwriter.ToString();
}
catch (Exception ex)
{
if (ex.InnerException != null)
ex = ex.InnerException;
return "Could not convert: " + ex.Message;
}
}
//Usage
var res = ObjectToXML(obj)
您需要使用以下类:
using System.IO;
using System.Xml;
using System.Xml.Serialization;
答案 16 :(得分:-1)
这是一个基本代码,有助于将C#对象序列化为xml:
using System;
public class clsPerson
{
public string FirstName;
public string MI;
public string LastName;
}
class class1
{
static void Main(string[] args)
{
clsPerson p=new clsPerson();
p.FirstName = "Jeff";
p.MI = "A";
p.LastName = "Price";
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
x.Serialize(Console.Out, p);
Console.WriteLine();
Console.ReadLine();
}
}