2012-11-06 106 views
2

我傳遞了一個xml文檔,其中缺少一些屬性給開發者。我需要缺少的值在結果對象中爲null,但是當前將反序列化爲零,將bools設爲false。XML將空屬性反序列化爲零併爲false

下面的示例顯示了一個文檔,其中vals反序列化正確,但沒有vals的文檔返回零和空值。

如何強制反序列化器不處理這樣的缺失屬性。

using System; 
using System.IO; 
using System.Xml; 
using System.Xml.Serialization; 

namespace SOQuestion 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      var resultWithVals = getObject(docWithVals()); 
      var resultWithoutVals = getObject(docWithoutVals()); 

      Console.WriteLine("WITH VALS"); 
      Console.WriteLine(resultWithVals.someBool); 
      Console.WriteLine(resultWithVals.someFloat); 
      Console.WriteLine(resultWithVals.someInt); 
      Console.WriteLine(resultWithVals.someString); 


      Console.WriteLine("WITHOUT VALS"); // nulls are returned here as zero and false 
      Console.WriteLine(resultWithoutVals.someBool); 
      Console.WriteLine(resultWithoutVals.someFloat); 
      Console.WriteLine(resultWithoutVals.someInt); 
      Console.WriteLine(resultWithoutVals.someString); 

      Console.ReadLine(); 


     } 

     public static XmlDocument docWithVals() 
     { 
      var doc = new XmlDocument(); 
      var el = (XmlElement)doc.AppendChild(doc.CreateElement("Result")); 
      el.SetAttribute("someString", "Hello World"); 
      el.SetAttribute("someBool", "true"); 
      el.SetAttribute("someInt", "1"); 
      el.SetAttribute("someFloat", "1.1"); 
      return doc; 

     } 

     public static XmlDocument docWithoutVals() 
     { 
      var doc = new XmlDocument(); 
      var el = (XmlElement)doc.AppendChild(doc.CreateElement("Result")); 
      el.SetAttribute("someString", "Hello World"); 
      return doc; 

     } 


     public static Result getObject(XmlDocument doc) 
     { 

       var mySerializer = new XmlSerializer(new Result().GetType()); 
       var myStream = new MemoryStream(); 
       doc.Save(myStream); 
       myStream.Position = 0; 
       var r = mySerializer.Deserialize(myStream); 
       return (Result)r; 
     } 

    } 

    [Serializable] 
    public class Result 
    { 
     [XmlAttribute] 
     public string someString { get; set; } 
     [XmlAttribute] 
     public bool someBool { get; set; } 
     [XmlAttribute] 
     public int someInt { get; set; } 
     [XmlAttribute] 
     public float someFloat { get; set; } 

    } 

} 

回答

2

您可以使用DefaultValueAttribute爲未初始化的字段提供默認值。你的情況,你可以寫

using System.ComponentModel; 
using System.Configuration; 

[XmlAttribute, DefaultValue(true)] 
public bool someBool { get; set; } 

編輯。請參閱note on MSDN的MSND頁的註釋:

一個DefaultValueAttribute將原因 成員要與屬性的 值自動 初始化。您必須在代碼中設置初始值 。

此問題已在XML serialization and DefaultValue("") related problem in c#中得到解決。 因此,要設置默認值,您必須在代碼中指定這些值。


我希望這會有所幫助。

+0

我看過那個。似乎沒有任何工作可以對空屬性進行反序列化。你能告訴我什麼具體我正在尋找與我的例子有關。謝謝 – Jules

+0

這個[XmlElementAttribute(IsNullable = false)]似乎在串行化到xml時不起作用,但不是從它反序列化。 – Jules

+0

此屬性在deserilising時不起作用。我試過[XmlAttribute,DefaultValue(null)],這也沒有任何影響。 – Jules

0

int s和float s不能有空值 - 它們的默認值分別是0false

如果他們應該被允許爲空,然後換到可空類型:

[Serializable] 
public class Result 
{ 
    [XmlAttribute] 
    public string someString { get; set; } 
    [XmlAttribute] 
    public bool? someBool { get; set; } 
    [XmlAttribute] 
    public int? someInt { get; set; } 
    [XmlAttribute] 
    public float? someFloat { get; set; } 
} 

注意,使用這種類型的東西現在必須檢查首先使用HasValue使用這些字段和前空值/或使用Value屬性訪問值。

+0

使它們可以爲空的類型在這裏不會有幫助,如文檔中所述。事實上,使它們可爲空意味着它們將變爲不可串行化的「XmlSerializer」! – MoonKnight

0

你可以嘗試使用這樣的:

[XmlAttribute] 
    public bool someBool { get; set; } 
    [XmlIgnore] 
    public bool someBoolSpecified { get; set; } 
    [XmlIgnore] 
    public bool? SomeBool 
    { 
     get 
     { 
      return someBoolSpecified ? someBool : default(bool?); 
     } 
     set 
     { 
      someBoolSpecified = value != default(bool?); 
      someBool = value ?? default(bool); 
     } 
    } 

由於每XmlSerializer documentation

另一種方法是使用一種特殊的模式創建由XmlSerializer識別的布爾字段,並將XmlIgnoreAttribute應用於該字段。該模式以propertyNameSpecified的形式創建。例如,如果有一個名爲「MyFirstName」的字段,則還會創建一個名爲「MyFirstNameSpecified」的字段,該字段指示XmlSerializer是否生成名爲「MyFirstName」的XML元素。這在以下示例中顯示。