序列化为XML时,在List中保留空值

时间:2014-12-09 10:33:06

标签: c# xml serialization

我有一个列表,可以包含不同类型的对象以及null值。当我将类序列化为XML时,我希望保留这些null值,但它们会自动删除。在IsNullable = true中设置XmlArrayItem attribute并没有改变任何内容。

我有以下简化的类结构:

public class MyClass
{
    [XmlArray("Items")]
    [XmlArrayItem("TypeA", typeof(A), IsNullable = true)]
    [XmlArrayItem("TypeB", typeof(B), IsNullable = true)]
    public ObservableCollection<Base> MyCollection { get; set; }
}

public class Base
{

}

public class A : Base
{

}

public class B : Base
{

}

如前所述,MyCollection可以包含2种不同类型的对象,但也包含null个值(在我的示例中,在索引0和2处)。

这是我的序列化代码:

var myClass = new MyClass();
myClass.MyCollection = new ObservableCollection<Base>
{
    null,
    new A(),
    null,
    new B()
};

var stream = new FileStream("C:\\temp\\test.xml", FileMode.Create);
var serializer = new XmlSerializer(typeof (MyClass));
serializer.Serialize(stream, myClass);

我得到以下XML输出:

<?xml version="1.0"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <TypeA />
    <TypeB />
  </Items>
</MyClass>

如何在列表中保留空值?我搜索了一段时间,但我只找到了如何删除null属性的解决方案。

1 个答案:

答案 0 :(得分:1)

实际上,我没有成功地使用IsNullable属性来处理XmlArrayItem,但是如果你不介意稍微不同的XML输出,你可以尝试:

public class MyClass
    {
        [XmlArray("Items", IsNullable = true)]
        public ObservableCollection<Base> MyCollection { get; set; }
    }

    [XmlInclude(typeof(A))]
    [XmlInclude(typeof(B))]
    public class Base
    {

    }

    [XmlType("TypeA")]
    public class A : Base
    {

    }

    [XmlType("TypeB")]
    public class B : Base
    {

    }

    public static void Test()
    {
        var myClass = new MyClass() { MyCollection = new ObservableCollection<Base> { new A(), null, new B(), null } };
        var wtr = new StreamWriter("C:\\avp\\test.xml");
        var s = new XmlSerializer(typeof(MyClass));
        s.Serialize(wtr, myClass);
        wtr.Close();
    }

然后你会得到那个输出:

<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <Base xsi:type="TypeA" />  
    <Base xsi:nil="true" />
    <Base xsi:type="TypeB" />
    <Base xsi:nil="true" />
  </Items>
</MyClass>