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

时间:2014-06-03 01:28:12

标签: c# serialization xml-serialization

我正在使用XmlSerializer将某些类序列化为XML文件。假设我有这个课程:

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

如果我按原样序列化这个类,我会得到:

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

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

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

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

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

但我有很多课程,有很多属性。有没有什么办法可以在我的XmlSerializer类中在类级别或事件中更好地设置此选项?


根据@ ulugbek-umirov给出的响应,我创建了以下代码,将XmlAttribute属性应用于我的类和基类中的所有属性,以防其他人需要它。这段代码特定于我的类,因为它只适用于以'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);
            }                
        }

    }

1 个答案:

答案 0 :(得分:1)

您可以将XmlAttributeOverrides类的实例与XmlSerializer一起使用。

你需要一些反思。以下是如何完成的基本思路。

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属性。

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