1

我的场景:

我有一个对象,我定义了一个用 XmlElement 标记修饰的属性,并且具有我定义的类型,其中一些类型是抽象的,可以设置为相应的派生类型。我想使用 XmlSerializer 将整个对象序列化为 XML,并且所有抽象的属性都应该序列化为 TypeName 设置为派生类型的 TypeName 的元素。

这是对象结构的示例:

[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
    [XmlElement(Type = typeof(DerivedClass))]
    public BaseClass TheBase { get; set; }
}

[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
    [XmlAttribute("AnAttribute")]
    public string AnAttribute { get; set; }

    [XmlElement("ANELEMENT")]
    public string AnElement { get; set; }

}

[XmlType(TypeName = "DERIVEDCLASS")]
public class DerivedClass : BaseClass
{
    [XmlElement("ANOTHERELEMENT")]
    public string AnotherElement { get; set; }

}

但是请注意,当我创建 MainObject 的新实例、填充它的属性并对其进行序列化时,生成的 XML 如下所示:

<MAINOBJECT>
    <BaseClass AnAttribute="">
            <ANELEMENT/>
            <ANOTHERELEMENT/>
    </BaseClass>
</MAINOBJECT>

我想要的是这样的:

<MAINOBJECT>
    <DERIVEDCLASS AnAttribute="">
            <ANELEMENT/>
            <ANOTHERELEMENT/>
    </DERIVEDCLASS>
</MAINOBJECT>

任何线索我在这里做错了什么?

4

3 回答 3

1

将 XmlElement 名称添加到TheBasein 中MainObject,如下所示:

[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
    [XmlElement("DERIVEDCLASS", Type = typeof(DerivedClass))]
    public BaseClass TheBase { get; set; }
}
于 2014-09-03T17:52:15.390 回答
1

在我看来,这里最好的解决方案是实现IXmlSerializable接口,以便您可以完全控制对象的序列化方式。当然,这需要更多的工作,但是如果您有类似这样的要求有些不同寻常,那么您可能还会遇到更多的怪癖,标准 XmlSerializer 将无法为您工作。

这里有一个很好的教程:如何正确实现 IXmlSerializable

此外,这里有一些很好的信息:Proper way to implement IXmlSerializable?

于 2014-09-04T12:09:05.200 回答
0

也许不是最好的解决方案,但是:

class Program
    {
        static void Main(string[] args)
        {
            XmlAttributes attrs = new XmlAttributes();

            XmlElementAttribute attr = new XmlElementAttribute();
            attr.ElementName = "DerivedClass";
            attr.Type = typeof(DerivedClass);

            attrs.XmlElements.Add(attr);

            XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();

            attrOverrides.Add(typeof(MainObject), "TheBase", attrs);

            XmlSerializer s = new XmlSerializer(typeof(MainObject), attrOverrides);

            StringWriter writer = new StringWriter();

            MainObject mo = new MainObject { TheBase = new DerivedClass { AnAttribute = "AnAttribute", AnElement = "AnElement", AnotherElement = "AotherElement" } };

            s.Serialize(writer, mo);
            Console.Write(writer.ToString());
        }
    }
于 2014-09-03T17:52:03.753 回答