默认情况下,如何使XmlSerializer生成属性而不是元素

14 .net c# xml-serialization xmlserializer

有没有办法使XmlSerializer原始类成员(例如字符串属性)序列化为XML属性,而不是XML元素,不必[XmlAttribute]在每个属性声明前写入?即是否有一个全局开关告诉XmlSerializer将所有原始类成员序列化为XML属性?

假设我们有以下类:

public class Person
{
    public string FirstName
    {
       ...
    }

    public string LastName
    {
       ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后XmlSerializer默认生成此代码:

<Person>
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
</Person>
Run Code Online (Sandbox Code Playgroud)

但是,我想要的是这段代码:

<Person FirstName="John" LastName="Doe"/>
Run Code Online (Sandbox Code Playgroud)

再说一遍:我想在没有[XmlAttribute](或没有XmlAttributeOverrides,这将是更多的工作)的情况下做到这一点.

一种可能的解决方案是使用通用后处理步骤,该步骤应用XSLT转换将元素转换为属性.但我想知道是否有一个更简单的解决方案.

Enr*_*lio 4

实现此目的的一种方法是在实现IXmlSerialized接口的基类中实现序列化逻辑。然后,要序列化为 XML 的类必须从该基类派生才能获得功能。

这是一个例子

public class XmlSerializableEntity : IXmlSerializable
{
    public XmlSchema GetSchema()
    {
        // Implementation omitted for clarity
    }

    public void ReadXml(XmlReader reader)
    {
        // Implementation omitted for clarity
    }

    public void WriteXml(XmlWriter writer)
    {
        var properties = from property in this.GetType().GetProperties()
                         where property.PropertyType.IsPrimitive ||
                               property.PropertyType == typeof(string)
                         select property;

        foreach (var property in properties)
        {
            var name = property.Name;
            var value = property.GetValue(this, null).ToString();
            writer.WriteAttributeString(name, value);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用Reflection从当前对象获取属性列表,该对象的类型是基元或String然后,使用提供的XmlWriter对象将这些属性作为属性写入 XML 输出。

要序列化的类只需继承即可XmlSerializableEntity自动获得此行为:

[Serializable]
public class Foo : XmlSerializableEntity
{
    public int Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)