序列化为XML片段 - 而不是XML文档

时间:2010-05-04 19:36:59

标签: .net xml xml-serialization

如何将XML可序列化对象序列化为XML片段(根元素中没有XML声明或命名空间引用)?

3 个答案:

答案 0 :(得分:19)

这是一种黑客方法,无需将整个输出字符串加载到XmlDocument中:

using System;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

public class Example
{
    public String Name { get; set; }

    static void Main()
    {
        Example example = new Example { Name = "Foo" };

        XmlSerializer serializer = new XmlSerializer(typeof(Example));

        XmlSerializerNamespaces emptyNamespace = new XmlSerializerNamespaces();
        emptyNamespace.Add(String.Empty, String.Empty);

        StringBuilder output = new StringBuilder();

        XmlWriter writer = XmlWriter.Create(output,
            new XmlWriterSettings { OmitXmlDeclaration = true });
        serializer.Serialize(writer, example, emptyNamespace);

        Console.WriteLine(output.ToString());
    }
}

答案 1 :(得分:1)

您应该能够像通常那样进行序列化,然后使用生成的文档中的Root属性。

您可能需要先清除元素的属性。

答案 2 :(得分:0)

顺便说一下,这太棒了。 我实现了这段代码,可以很容易地将xml片段快速地作为类使用,然后在完成后只需替换节点。这使得代码和xml之间的过渡非常容易。

首先创建一些扩展方法。

public static class SerializableFragmentExtensions
{
    public static XElement ToElement(this ISerializableFragment iSerializableFragment)
    {
        var serializer = new XmlSerializer(iSerializableFragment.GetType());
        var emptyNamespace = new XmlSerializerNamespaces();
        emptyNamespace.Add(String.Empty, String.Empty);

        var output = new StringBuilder();

        var writer = XmlWriter.Create(output,
            new XmlWriterSettings { OmitXmlDeclaration = true });
        serializer.Serialize(writer, iSerializableFragment, emptyNamespace);
        return XElement.Parse(output.ToString(), LoadOptions.None);
    }
    public static T ToObject<T>(this XElement xElement)
    {
        var serializer = new XmlSerializer(typeof (T));
        var reader = xElement.CreateReader();
        var obj = (T) serializer.Deserialize(reader);
        return obj;
    }
}

下一步实现所需的界面(标记界面 - 我知道你不应该这样做,但我认为这是完美的理由。)

public interface ISerializableFragment
{
}

现在你所要做的就是装饰任何Serializable类,你想用接口转换为XElement Fragment。

[Serializable]
public class SomeSerializableClass : ISerializableFragment
{
    [XmlAttribute]
    public string SomeData { get; set; }
}

最后测试代码。

    static void Main(string[] args)
    {
        var someSerializableClassObj = new SomeSerializableClass() {SomeData = "Testing"};
        var element = someSerializableClass.ToElement();
        var backToSomeSerializableClassObj = element.ToObject<SomeSerializableClass>();
    }

再次感谢这个非常有用的代码。