8

我想将一个类序列化为 XML,并为其分配一个 XML 属性。片段:

    [XmlType(TypeName = "classmy")]
    public class MyClass2 : List<object>
    {
        [XmlAttribute(AttributeName = "myattr")]
        public string Name { get; set; }
    }

    public class MyConst
    {
        public MyConst()
        {
            MyClass2 myClass2 = new MyClass2 { 10, "abc" };

            myClass2.Name = "nomm";

            XmlSerializer serializer = new XmlSerializer(typeof(MyClass2));
            serializer.Serialize(Console.Out, myClass2);
        }
    }

但生成的 XML 看起来像这样

<?xml version="1.0" encoding="IBM437"?>
<classmy xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <anyType xsi:type="xsd:int">10</anyType>
  <anyType xsi:type="xsd:string">abc</anyType>
</classmy>

一切都很好,唯一的例外是 myClass2.Name 没有序列化。我期待着一些东西

<classmy myattr="nomm" [...]>[...]</classmy>

...为什么不序列化,怎么可能?

4

3 回答 3

4

不要派生List<T>,用成员创建类List

[XmlType(TypeName = "classmy")]
public class MyClass2
{
    [XmlAttribute(AttributeName = "Items")]
    List<object> Items { get; set; } //need to change type in `<>`

    [XmlAttribute(AttributeName = "myattr")]
    public string Name { get; set; }
}
于 2012-08-08T09:29:46.640 回答
3

XmlSerializer 以特殊方式处理 List<>:

如果满足某些要求,XmlSerializer 可以以不同方式处理实现 IEnumerable 或 ICollection 的类。实现 IEnumerable 的类必须实现采用单个参数的公共 Add 方法。Add 方法的参数必须与从 GetEnumerator 方法返回的 IEnumerator.Current 属性返回的类型一致(多态)。除了 IEnumerable 之外,实现 ICollection 的类(例如 CollectionBase)必须具有采用整数的公共 Item 索引属性(C# 中的索引器),并且必须具有整数类型的公共 Count 属性。传递给 Add 方法的参数必须与从 Item 属性返回的类型相同,或者是该类型的基类型之一。对于实现 ICollection 的类,另请注意,公共字段和属性将不会被序列化,但返回另一个集合类(实现 ICollection 的)的公共字段除外MSDN - 滚动到 XML 序列化注意事项

这就是为什么它将您的类序列化为仅对象列表,而没有您的属性。最好的解决方案是将 List 作为类公共属性包含在内并将其标记为 XmlElement。

于 2012-08-08T10:36:07.370 回答
2

替代解决方案:使用数组而不是列表和 XmlElement

    [XmlType(TypeName = "classmy")]
    public class MyClass2
    {
        [XmlElement(ElementName = "Items")]
        public object[] Items { get; set; }
        [XmlAttribute(AttributeName = "myattr")]
        public string Name { get; set; }
    }
于 2012-08-08T09:48:30.383 回答