当您创建
XmlSerializer
时,可以通过将
XmlAttributeOverrides
实例传递给它来实现此操作。您可以使用它将默认值更改为其他值,或将其设置为 null 以有效地删除它。
XmlAttributeOverrides attributeOverrides = new XmlAttributeOverrides();
var attributes = new XmlAttributes()
{
XmlDefaultValue = null,
XmlAttribute = new XmlAttributeAttribute()
};
attributeOverrides.Add(typeof(Person), "Name", attributes);
var serializer = new XmlSerializer(typeof(Person), attributeOverrides);
var person = new Person { Name = "John" };
using (var sw = new StringWriter())
{
using (var writer = XmlWriter.Create(sw))
{
serializer.Serialize(writer, person);
var xml = sw.ToString();
}
}
更新:以上意味着您必须在每个要更改的属性上再次提供其他无关属性。如果您有很多属性并且只想删除所有属性的默认值,这可能有点繁琐。可以使用下面的类来保留其他自定义属性,同时仅删除一种类型的属性。如果需要,可以进一步扩展以仅对某些属性执行此操作。
public class XmlAttributeOverrideGenerator<T>
{
private static XmlAttributeOverrides _overrides;
private static Type[] _ignoreAttributes = new Type[] { typeof(DefaultValueAttribute) };
static XmlAttributeOverrideGenerator()
{
_overrides = Generate();
}
public static XmlAttributeOverrides Get()
{
return _overrides;
}
private static XmlAttributeOverrides Generate()
{
var xmlAttributeOverrides = new XmlAttributeOverrides();
Type targetType = typeof(T);
foreach (var property in targetType.GetProperties())
{
XmlAttributes propertyAttributes = new XmlAttributes(new CustomAttribProvider(property, _ignoreAttributes));
xmlAttributeOverrides.Add(targetType, property.Name, propertyAttributes);
}
return xmlAttributeOverrides;
}
public class CustomAttribProvider : ICustomAttributeProvider
{
private PropertyInfo _prop = null;
private Type[] _ignoreTypes = null;
public CustomAttribProvider(PropertyInfo property, params Type[] ignoreTypes)
{
_ignoreTypes = ignoreTypes;
_prop = property;
}
public object[] GetCustomAttributes(bool inherit)
{
var attribs = _prop.GetCustomAttributes(inherit);
if (_ignoreTypes == null) return attribs;
return attribs.Where(attrib => IsAllowedType(attrib)).ToArray();
}
private bool IsAllowedType(object attribute)
{
if (_ignoreTypes == null) return true;
foreach (Type type in _ignoreTypes)
if (attribute.GetType() == type)
return false;
return true;
}
public object[] GetCustomAttributes(Type attributeType, bool inherit)
{
throw new NotImplementedException();
}
public bool IsDefined(Type attributeType, bool inherit)
{
throw new NotImplementedException();
}
}
}
使用方法:
XmlAttributeOverrides attributeOverrides = XmlAttributeOverrideGenerator<Person>.Get()
var serializer = new XmlSerializer(typeof(Person), attributeOverrides)
attributeOverrides.Add(typeof(Person), "Name", new XmlAttributes() { XmlDefaultValue = null });
那么所有的XmlAttributes都将被覆盖,在我的例子中[System.Xml.Serialization.XmlAttribute()]
将不存在。是否有一种方法仅覆盖DefaultValue
并保留所有其他属性不变? - Mykhailo Seniutovych