如何将对象序列化为xml但不将其作为xml文档的根元素

时间:2010-05-26 08:43:05

标签: c# xml xml-serialization

我有以下对象:

public class MyClass
{
    public int Id { get; set;}
    public string Name { get; set; }
}

我想将其序列化为以下xml字符串:

<MyClass>
    <Id>1</Id>
    <Name>My Name</Name>
</MyClass>

不幸的是,当我使用XMLSerializer时,我得到一个看起来像的字符串:

<?xml version="1.0" encoding="utf-8"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
    <Id>1</Id>
    <Name>My Name</Name>
</MyClass>

我不希望MyClass成为文档的根元素,而是我最终想要将字符串与其他类似的序列化对象一起添加,这些对象将位于更大的xml文档中。

即。最终我将有一个xml字符串,如下所示:

<Classes>
    <MyClass>
        <Id>1</Id>
        <Name>My Name</Name>
    </MyClass>
    <MyClass>
        <Id>1</Id>
        <Name>My Name</Name>
    </MyClass>
</Classes>"

我的第一个想法是按如下方式创建一个类:

public class Classes
{
    public List<MyClass> MyClasses { get; set; }
}

...但是这只是添加一个名为MyClasses的节点来包装MyClass ....

列表

我的直觉是,我正在以错误的方式接近这一点,而且我缺乏创建xml文件的经验并没有帮助我指向.NET框架的某些部分或其他简化这一点的库。 / p>

4 个答案:

答案 0 :(得分:3)

您需要使用XmlWriter对象 - 这使您可以完全控制XML的呈现方式。您还需要将XmlSerializerNamespaces实例传递给序列化程序以获得所需内容。

下面的示例程序完全符合您的要求(注意XmlWriter如何使用XmlWriterSettings进行初始化,以及XmlNamespaces实例如何传递给序列化程序):

    public class MyClass
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }


    class Program
    {
        static void Main(string[] args)
        {
            var xml = new StringBuilder();

            using (var writer = 
                XmlWriter.Create(xml, 
                        new XmlWriterSettings { Indent = true, 
                          ConformanceLevel = ConformanceLevel.Auto, 
                          OmitXmlDeclaration = true }))
            {
                MyClass myClass = new MyClass { Id = 1, Name = "My Name" };

                var ns = new XmlSerializerNamespaces();
                ns.Add("", "");

                var xs = new XmlSerializer(typeof(MyClass), "");
                xs.Serialize(writer, myClass, ns);
            }

            Console.WriteLine(xml.ToString());

            // pause program execution to review results...
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }


//Result:
<MyClass>
<Id>1</Id>
<Name>My Name</Name>
</MyClass>

答案 1 :(得分:1)

不要使用XmlSerializer,而是使用DataContracts。创建一个新类型Classes,继承List<MyClass>,如:

[CollectionDataContract(Name = "Classes")]
public class Classes : List<MyClass>
{
}

[DataContract(Name = "MyClass")]
public class MyClass
{
    [DataMember(Name="Id")]
    public int Id { get;set; }
}

现在使用DataContractSerializer序列化您的Classes实例:

Classes myItems = new Classes();
myItems.Add( ... );

DataContractSerializer serializer = new DataContractSerializer(typeof(Classes));
serializer.WriteObject( /* some stream */, myItems);

回应评论

使用类似的东西:

[CollectionDataContract(Name = "MyClasses1")]
public class MyClassesOne : List<MyClass> { }

[CollectionDataContract(Name = "MyClasses2")]
public class MyClassesTwo : List<MyClass> { }

[DataContract(Name = "Classes")]
public class Classes {
    [DataMember] public MyClassesOne MyClasses1 { get; set; }
    [DataMember] public MyClassesTwo MyClasses2 { get; set; }
}

任何客户都更容易消费。

答案 2 :(得分:0)

元素作为根节点应该不是问题。您可以稍后将它(它将是XmlDocument的DocumentElement)导入另一个XmlDocument。

答案 3 :(得分:0)

您可以查看XStream for .NET。这个tutorial向您展示了如何实现您想要的目标。