简体   繁体   English

将类中的所有属性序列化为属性而不是元素

[英]Serialize all properties in a class as attributes instead of elements

I'm using XmlSerializer to serialize some classes to a XML File. 我正在使用XmlSerializer将某些类序列化为XML文件。 Suppose I have this class: 假设我有这个课:

public class ClassToSerialize
{
    public string PropertyA { get; set; }
    public string PropertyB { get; set; }
    public string PropertyC { get; set; }
}

if I serialize this class as it is, i'll get: 如果我按原样序列化此类,我将得到:

<ClassToSerialize>
    <PropertyA>{Value}</PropertyA}
    <PropertyB>{Value}</PropertyB}
    <PropertyC>{Value}</PropertyC}
</ClassToSerialize>

I'd like the properties to be serialized as xml attributes, instead of elements. 我希望将属性序列化为xml属性,而不是元素。 I know i can achieve this by using [XmlAttribute] in each property: 我知道我可以通过在每个属性中使用[XmlAttribute]实现此目的:

public class ClassToSerialize
{
    [XmlAttribute]
    public string PropertyA { get; set; }

    [XmlAttribute]
    public string PropertyB { get; set; }

    [XmlAttribute]
    public string PropertyC { get; set; }
}

But i have a lot of classes, with a lot of properties. 但是我有很多类,有很多特性。 Is there any way I can set this option in the class level, or event better, in my XmlSerializer class? 有什么办法可以在XmlSerializer类的类级别或更好的事件中设置此选项?


Based on the response given by @ulugbek-umirov, i create the following code to apply the XmlAttribute attribute to all properties in my class and base classes, in case anyone else needs it. 基于@ ulugbek-umirov给出的响应,我创建了以下代码,以将XmlAttribute属性应用于我的类和基类中的所有属性,以防万一其他人需要它。 This code is specific to my classes, because it only works with classes that starts with 'x', but If you need to adapt to your case it will easy. 该代码特定于我的类,因为它仅适用于以'x'开头的类,但是如果需要适应您的情况,这将很容易。

private static void GenerateXmlAttributeOverrides(XmlAttributeOverrides overrides, Type type)
{
    foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if ((propertyInfo.PropertyType.IsPrimitive || propertyInfo.PropertyType == typeof(string)))
            {
                if (!(propertyInfo.Name.EndsWith("Specified")
                    || HasAttribute(propertyInfo, typeof(XmlElementAttribute))
                    || HasAttribute(propertyInfo, typeof(XmlAttributeAttribute))))
                {
                    overrides.Add(type, propertyInfo.Name, new XmlAttributes { XmlAttribute = new XmlAttributeAttribute() });
                }
            }
            else if (propertyInfo.PropertyType.IsGenericType)
            {
                Type[] tipos = propertyInfo.PropertyType.GetGenericArguments();
                if (tipos != null && tipos.Length > 0 && tipos[0].Name.StartsWith("x"))
                    GenerateXmlAttributeOverrides(overrides, tipos[0]);
            }
            else if (propertyInfo.PropertyType.Name.StartsWith("x")) 
            {
                GenerateXmlAttributeOverrides(overrides, propertyInfo.PropertyType);
            }                
        }

    }

You can use instance of XmlAttributeOverrides class with XmlSerializer. 您可以将XmlAttributeOverrides类的实例与XmlSerializer一起使用。

You will need a bit of reflection. 您将需要一些反思。 The following is the basic idea how it can be done. 以下是如何实现的基本思想。

static XmlAttributeOverrides GenerateXmlAttributeOverrides(Type type)
{
    XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides();
    foreach(PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
        xmlAttributeOverrides.Add(type, propertyInfo.Name, new XmlAttributes { XmlAttribute = new XmlAttributeAttribute() });
    return xmlAttributeOverrides;
}

Usage: 用法:

XmlAttributeOverrides overrides = GenerateXmlAttributeOverrides(typeof(ClassToSerialize));
XmlSerializer serializer = new XmlSerializer(typeof(ClassToSerialize), overrides);

You may wish to add check that property is of simple type and that it is not abbreviated with XmlElement or XmlAttribute attributes. 您可能希望添加检查属性是否为简单类型,以及是否不使用XmlElementXmlAttribute属性缩写。

static XmlAttributeOverrides GenerateXmlAttributeOverrides(Type type)
{
    XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides();
    foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        if ((propertyInfo.PropertyType.IsPrimitive || propertyInfo.PropertyType == typeof(string)) &&
            !propertyInfo.GetCustomAttributes().Any(a => a.GetType() == typeof(XmlElementAttribute) ||
                                                         a.GetType() == typeof(XmlAttributeAttribute)))
            xmlAttributeOverrides.Add(type, propertyInfo.Name, new XmlAttributes { XmlAttribute = new XmlAttributeAttribute() });
    }
    return xmlAttributeOverrides;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM