根据W3C,XSD布尔数据类型定义为0,1,true或false。外部方提供了一个我没有影响的xsd,因为您可能已经猜到了它们所需的布尔值不是C#XmlSerializer序列化布尔值的默认值。不接受真和假,只有0和1.更糟糕的是,序列化为xml的类是由xsd.exe自动生成的,因此我不想改变这些类,因为开发人员跟在我后面运行xsd.exe工具后,很可能会忘记这个额外的步骤。
因此,以下解决方案存在问题:
[XmlIgnore]
public bool MyValue { get; set; }
/// <summary>Get a value purely for serialization purposes</summary>
[XmlElement("MyValue")]
public string MyValueSerialize
{
get { return this.MyValue ? "1" : "0"; }
set { this.MyValue = XmlConvert.ToBoolean(value); }
}
同样根据我的理解,未来有可能将一些布尔值序列化为0或1而其他布尔值变为真或假(我知道......)。在出现这种情况之前,实现我的自定义XmlSerializer(参见:XML Serialize boolean as 0 and 1)可能是一个可接受的解决方案,但在此之前,我希望有人对以下有趣的可能性有一些提示:
假设xsd.exe已生成以下代码:
namespace MyUnitTests.Classes {
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:XX:YYYY:01")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:XX:01", IsNullable = false)]
public partial class MyRootClass {
public MyBoolClass MyBoolClass { get; set; }
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "XX:ZZ:01")]
public partial class MyBoolClass {
[System.Xml.Serialization.XmlElementAttribute("Node")]
public bool Item { get; set; }
}
}
所以我的想法是MyBoolClass是一个部分类,我可以在一个单独的定义中提供我自己的自定义实现,我在其中处理真正的 - &gt; 1假 - &gt; 0问题。
我的代码如下:
namespace MyUnitTests.Classes {
public interface IMyBoolClass {
[XmlIgnore]
bool Item { get; set; }
}
public partial class MyBoolClass : IMyBoolClass {
[XmlElement("Node")]
public string SerializableItem {
get { return this.Item ? "1" : "0"; }
set { this.Item = System.Xml.XmlConvert.ToBoolean(value); }
}
}
}
所以我有一个IMyBoolClass接口,我设计用来处理XmlIgnore并声明应该序列化实际0和1的属性SerializableItem。不幸的是,发生的异常表明XmlIgnore没有应用于MyBoolClass.Item,即由xsd.exe生成。
我有以下UnitTest
[TestMethod]
public void TestMethod2() {
MyRootClass root = new MyRootClass() {
MyBoolClass = new MyBoolClass() {
Item = false
}
};
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyRootClass));
using (StringWriter writer = new StringWriter()) {
xmlSerializer.Serialize(writer, root);
string xml = writer.ToString();
}
}
发生以下异常:
There was an error reflecting property 'MyBoolClass
There was an error reflecting property 'Item'
The XML element 'Node' from namespace 'XX:ZZ:01' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element
显然正在改变:
[XmlElement("Node")]
在我自己的MyBoolClass部分定义中:
[XmlElement("Node1")]
解决问题并产生以下XML:
<?xml version="1.0" encoding="utf-16"?>
<MyRootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:XX:01">
<MyBoolClass xmlns="urn:XX:YYYY:01">
<Node1 xmlns="XX:ZZ:01">0</Node1>
<Node xmlns="XX:ZZ:01">false</Node>
</MyBoolClass>
</MyRootClass>
所以问题如何“隐藏”:
public bool Item { get; set; }
在xsd.exe为XmlSerializer生成的类MyBoolClass中?
任何提示和技巧都将受到高度赞赏,如果有人有其他一些好主意,我将非常感激。