2012-11-06 70 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元素。这在以下示例中显示。