2011-06-18 48 views
6

我正在尝试以特定格式生成xml文档。我想跳过序列化属性取决于属性的值。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()); 

如果设置为false,我想整个房地产不序列化,我得到的XML应该是

<Parent> 
    <myChild2>default</myChild2> 
</Parent> 

而不是

<Parent> 
    <myChild/> 
    <myChild2>default</myChild2> 
</Parent> 

有一些方法可以让我做这干净地与IXmlSerializable或其他?

谢谢!

回答

6

有一个ShouldSerialize *模式(通过TypeDescriptor出台,但通过代码的一些其他领域,如XmlSerializer的认可):

public bool ShouldSerializemyChild() { 
    return myChild != null && myChild.Set; 
} 

这应该排序。

但是,一个更简单的选项是将其指定为空。

+0

我有很多是所有类型的子性质的,我不希望有每一个ShouldSerialize。我可能将我的所有属性设置为null,在我序列化之前未设置.. – TrevDev

+0

我发布了一个答案,通过在序列化之前调用的方法将值动态设置为null。您是否有更清晰的分配空值的想法? – TrevDev

+0

@Thx不是真的... –

0

如果“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; } 
} 
0

我觉得这可能是工作,虽然你migh有此改变Equals方法

[DefaultValue(new Child())] 
public Child myChild{ get; set; } 
+0

属性参数必须是一个常数 – TrevDev

0

只写了这段代码的乐趣,也许在这个过程中学到了一些东西。 如果该属性包含一个名为Set的方法返回bool,并且它的当前值为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); 
      } 
     } 
    } 
}