3

我试图找出如何解决从驼峰字符串中序列化布尔类型的问题。

我有以下xml

<Root>
  <BoolElement>
     False
  </BoolElement>
</Root>

和以下课程

[XmlRoot("Root")]
public class RootObj{
  [XmlElement("BoolElement")]
  public bool BoolElement{get;set;}
}

这将产生错误。

如果我使用相同的类并将“False”重命名为“false”,它将起作用。问题是我无法编辑 xml。

有谁知道我该如何解决这个问题?

4

3 回答 3

7

您可以使用支持字段来帮助反序列化此无效 XML(我说无效,因为根据 xsd:boolean 模式False是无效值):

[XmlRoot("Root")]
public class RootObj
{
    [XmlElement("BoolElement")]
    public string BackingBoolElement
    {
        set
        {
            BoolElement = bool.Parse(value.ToLower());
        }
        get
        {
            return BoolElement.ToString();
        }
    }

    [XmlIgnore]
    public bool BoolElement { get; set; }
}
于 2012-05-09T07:50:34.747 回答
4

False不是xsd:boolean 的有效值(但正如您所注意到false的那样0) - 如果您无法更改源数据,那么您可以拥有一个单独的属性,纯粹用于 XML 序列化:

[XmlRoot("Root")]
public class RootObj{
  [XmlElement("BoolElement")]
  public string BoolElementForSerialization
  {
     get
     {
         return (this.BoolElement ? "True" : "False");
     }
     set
     {
         this.BoolElement = (string.Compare(value, "false", StringComparison.OrdinalIgnoreCase) != 0);
     }
  }

  [XmlIgnore]
  public bool BoolElement{get;set;}
}
于 2012-05-09T07:51:22.487 回答
0

我创建了一个可以从任何字符串反序列化的新布尔类型。它可能并不完美,但它适合我当时的需求。

对于您要使用的类,只需将数据类型从 bool 更改为 SerializableBoolean:

[XmlRoot("Root")]
public class RootObj{
  [XmlElement("BoolElement")]
  public SerializableBoolean BoolElement{get;set;}
}

然后,您可以像使用任何普通 bool 数据类型一样使用 BoolElement 属性:

RootObj myObj = new RootObj();
if (myObj.BoolElement) { ... }

这是 SerializableBoolean 类的代码,请注意,此代码仅处理反序列化,我的目的不需要序列化为 xml,因此未实现。

[System.Diagnostics.DebuggerDisplay("{Value}")]
public struct SerializableBoolean: System.Xml.Serialization.IXmlSerializable
{
    private bool Value { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is string stringBoolean)
        {
            bool.TryParse(stringBoolean, out bool boolean);
            return Value == boolean;
        }
        else if (obj is bool boolean)
        {
            return Value == boolean;
        }
        else if (obj is SerializableBoolean serializableBoolean)
        {
            return Value == serializableBoolean.Value;
        }
        else
        {
            return Value == Convert.ToBoolean(obj);
        }
    }

    public override int GetHashCode()
    {
        return -1937169414 + Value.GetHashCode();
    }

    public XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {
        Value = Convert.ToBoolean(reader.ReadElementContentAsString());
    }

    public void WriteXml(XmlWriter writer)
    {
        throw new NotImplementedException();
    }

    public static bool operator ==(SerializableBoolean obj1, bool obj2)
    {
        return obj1.Value.Equals(obj2);
    }
    public static bool operator !=(SerializableBoolean obj1, bool obj2)
    {
        return !obj1.Value.Equals(obj2);
    }

    public static implicit operator SerializableBoolean(string value)
    {
        return new SerializableBoolean() { Value = Convert.ToBoolean(value) };
    }

    public static implicit operator SerializableBoolean(bool value)
    {
        return new SerializableBoolean() { Value = value };
    }

    public static implicit operator bool(SerializableBoolean b)
    {
        return b.Value;
    }
}
于 2018-05-16T07:49:35.467 回答