【问题标题】:Can I Serialize XML straight to a string instead of a Stream with C#?我可以将 XML 直接序列化为字符串而不是使用 C# 的流吗?
【发布时间】:2010-11-11 10:11:59
【问题描述】:

This example 使用StringWriter 保存序列化数据,然后调用ToString() 给出实际的string 值:

Person john = new Person();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));
StringWriter stringWriter = new StringWriter();
xmlSerializer.Serialize(stringWriter, john);
string serializedXML = stringWriter.ToString();

有没有更简单/更清洁的方法来做到这一点?所有Serialize() 重载似乎都使用Stream 或Writer。

更新:问了一个关于 serializing an IEnumerable via an Extension Method 的类似问题。

【问题讨论】:

    标签: c# xml-serialization


    【解决方案1】:

    我创建了这个辅助方法,但我还没有测试它。更新了 orsogufo 的 cmets 的代码(两次):

    private string ConvertObjectToXml(object objectToSerialize)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(objectToSerialize.GetType());
        StringWriter stringWriter = new StringWriter();
    
        xmlSerializer.Serialize(stringWriter, objectToSerialize);
    
        return stringWriter.ToString();
    }
    

    【讨论】:

    • 你用 Convert.ChangeType 做什么?
    • 出于某种原因,我脑子里想我需要将它转换回正确的类型......但我认为你是对的,没有必要。代码将被更新。
    • 事实上不,序列化程序将通用对象作为参数(因此浪费了您的额外转换)。另请注意,您不需要显式传递类型,您可以询问对象的类型。当然,除非您想将一个对象序列化为不同类型的对象(不明白为什么要这样做,但您永远不知道)。
    • 尝试将对象序列化为另一种类型可能行不通,除非它是我假设的基类或接口。然后更新我的代码以删除类型引用。
    【解决方案2】:

    扩展方法的乐趣...

    var ret = john.ToXmlString()
    

    public static class XmlTools
    {
        public static string ToXmlString<T>(this T input)
        {
            using (var writer = new StringWriter())
            {
                input.ToXml(writer);
                return writer.ToString();
            }
        }
        public static void ToXml<T>(this T objectToSerialize, Stream stream)
        {
            new XmlSerializer(typeof(T)).Serialize(stream, objectToSerialize);
        }
    
        public static void ToXml<T>(this T objectToSerialize, StringWriter writer)
        {
            new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
        }
    }
    

    【讨论】:

    • 殴打...被... 9...秒... aaarrrggghhh!
    • 啊,是的!完全忘记了!
    • 耶...我通常是迟到的海报,以确保我的代码在我提交之前有效。
    • 我也是,但这是一种没有回报的态度:)
    • 这真的是扩展方法的恰当使用吗?我个人认为不是,但这样的意见不值得投反对票,所以我没有(只是如果其他人这样做,你不这么认为)。
    【解决方案3】:

    或多或少与您相同的解决方案,只是使用扩展方法:

    static class XmlExtensions {
    
        // serialize an object to an XML string
        public static string ToXml(this object obj) {
            // remove the default namespaces
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add(string.Empty, string.Empty);
            // serialize to string
            XmlSerializer xs = new XmlSerializer(obj.GetType());
            StringWriter sw = new StringWriter();
            xs.Serialize(sw, obj, ns);
            return sw.GetStringBuilder().ToString();
        }
    
    }
    
    [XmlType("Element")]
    public class Element {
        [XmlAttribute("name")]
        public string name;
    }
    
    class Program {
        static void Main(string[] args) {
            Element el = new Element();
            el.name = "test";
            Console.WriteLine(el.ToXml());
        }
    }
    

    【讨论】:

    • +1 表示不同的做事方式,还有一个完整的例子!
    • StringWriter 周围缺少 using,在这种情况下它可能不会导致任何问题,但它应该始终存在,以防万一它被更改为获取流。
    【解决方案4】:

    似乎没有人真正回答他的问题,不,不使用流或写入器对象就无法生成 XML 字符串。

    【讨论】:

    • 由于Serializer 在内部使用写入,它不能直接使用StringStringBuilderStringWriter 基本上没有开销,所以看不出有什么问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 2014-12-24
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多