2011-06-18 63 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); 
      } 
     } 
    } 
}