将类中的所有属性序列化为属性而不是元素 [英] Serialize all properties in a class as attributes instead of elements

查看:32
本文介绍了将类中的所有属性序列化为属性而不是元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 XmlSerializer 将一些类序列化为 XML 文件.假设我有这个类:

I'm using XmlSerializer to serialize some classes to a XML File. 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>

我希望将属性序列化为 xml 属性,而不是元素.我知道我可以通过在每个属性中使用 [XmlAttribute] 来实现这一点:

I'd like the properties to be serialized as xml attributes, instead of elements. I know i can achieve this by using [XmlAttribute] in each property:

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

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

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

但是我有很多类,有很多属性.有什么方法可以在我的 XmlSerializer 类中的类级别或更好的事件中设置此选项?

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?

根据@ulugbek-umirov 给出的响应,我创建了以下代码以将 XmlAttribute 特性应用于我的类和基类中的所有属性,以防其他人需要它.此代码特定于我的类,因为它仅适用于以x"开头的类,但如果您需要适应您的情况,这将很容易.

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. 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.

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);
            }                
        }

    }

推荐答案

您可以使用 XmlAttributeOverrides 类和 XmlSerializer.

You can use instance of XmlAttributeOverrides class with 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;
}

用法:

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

您可能希望添加检查属性是否为简单类型,并且它没有用 XmlElementXmlAttribute 属性缩写.

You may wish to add check that property is of simple type and that it is not abbreviated with XmlElement or XmlAttribute attributes.

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;
}

这篇关于将类中的所有属性序列化为属性而不是元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆