Xml序列化动态忽略
本文关键字:动态 序列化 Xml | 更新日期: 2023-09-27 17:59:50
我正在尝试生成一个特定格式的xml文档。我希望根据属性的值跳过序列化属性。
public class Parent
{
public Parent()
{
myChild = new Child();
myChild2 = new Child() { Value = "Value" };
}
public Child myChild { get; set; }
public Child myChild2 { get; set; }
}
public class Child
{
private bool _set;
public bool Set { get { return _set; } }
private string _value = "default";
[System.Xml.Serialization.XmlText()]
public string Value
{
get { return _value; }
set { _value = value; _set = true; }
}
}
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(Parent));
x.Serialize(Console.Out, new Parent());
如果Set为false,我希望整个属性不被序列化,我得到的xml应该是
<Parent>
<myChild2>default</myChild2>
</Parent>
代替
<Parent>
<myChild/>
<myChild2>default</myChild2>
</Parent>
有没有什么方法可以用IXmlSerializable或其他任何东西干净地做到这一点?
谢谢!
存在ShouldSerialize*模式(由TypeDescriptor引入,但由其他一些代码区域(如XmlSerializer)识别):
public bool ShouldSerializemyChild() {
return myChild != null && myChild.Set;
}
这应该可以分类。
不过,一个更简单的选择是将其赋值为null。
如果"mychild"是由数组定义的,我认为它可以做得很好。。。
public class Parent
{
public Parent()
{
myChild = new Child[]{ new Child(){Value = "Value"}};
//myChild2 = new Child() { Value = "Value" };
}
public Child[] myChild { get; set; }
//public Child myChild2 { get; set; }
}
我认为这是可行的,尽管您可能需要重写Equals方法
[DefaultValue(new Child())]
public Child myChild{ get; set; }
写这段代码只是为了好玩,也许可以在这个过程中学到一些东西。如果任何属性包含一个返回bool的名为set的方法,并且其当前值为false,那么它应该将该属性设置为null。通过将值设置为false,应该可以解决序列化程序的问题。任何建议:
public static void RemoveUnsetObjects(object currentObject)
{
var type = currentObject.GetType();
if (currentObject is IEnumerable)
{
IEnumerable list = (currentObject as IEnumerable);
foreach (object o in list)
{
RemoveUnsetObjects(o);
}
}
else
{
foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
{
var propertyValue = p.GetValue(currentObject, null);
if (propertyValue == null)
continue;
var setPropInfo = p.PropertyType.GetProperty("Set", typeof(bool));
if (setPropInfo != null)
{
var isSet = (bool)setPropInfo.GetValue(propertyValue, null);
if (!isSet)
{
p.SetValue(currentObject, null, null);
}
}
else
{
RemoveUnsetObjects(propertyValue);
}
}
}
}