我继承了一个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表示形式?


当前回答

可以将下面的函数复制到任何对象,以使用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];
    }
}

其他回答

可以将下面的函数复制到任何对象,以使用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];
    }
}

这里有一个关于如何做到这一点的很好的教程

基本上应该使用System.Xml.Serialization.XmlSerializer类来做到这一点。

我修改了我的返回一个字符串,而不是像下面这样使用一个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();

现在可能太晚了,但是只有用户定义的命名空间是序列化的:

public static string XmlSerialize<T>(this T obj) where T : class
        {
            Type serialType = typeof(T);
            var xsSubmit = new XmlSerializer(serialType);

            XmlWriterSettings xws = new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = true };
            

            var Namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] {           
            new XmlQualifiedName(string.Empty,  GetXmlNameSpace(serialType) ?? string.Empty )


        });
 private static string GetXmlNameSpace(Type target)
        {
            XmlRootAttribute attribute = (XmlRootAttribute)Attribute.GetCustomAttribute(target, typeof(XmlRootAttribute));
            return attribute == null ? null : attribute.Namespace;
        }

并在自定义类中定义命名空间

 [XmlRoot("IdentityTerminal",Namespace = "http://my-name-space/XMLSchema")]
   
    public class IdentityTerminal
    {
    }

这段代码允许只使用用户定义的名称空间,而忽略默认的名称空间。

扩展类:

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();

只是引用名称空间持有您的扩展方法在文件中,你想使用它,它将工作(在我的例子中,它将是:使用myproject . extensions;)

请注意,如果您想使扩展方法只特定于一个特定的类(例如。, Foo),你可以在扩展方法中替换T参数。

序列化(这个Foo值){…}