Blo*_*ard 15 c# boolean xml-serialization
我正在将xml发送到另一个程序,它希望布尔标志为"是"或"否",而不是"真"或"假".
我有一个类定义如下:
[XmlRoot()]
public class Foo {
public bool Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我序列化它时,我的输出如下所示:
<Foo><Bar>true</Bar></Foo>
Run Code Online (Sandbox Code Playgroud)
但我希望它是这样的:
<Foo><Bar>yes</Bar></Foo>
Run Code Online (Sandbox Code Playgroud)
我可以在序列化时这样做吗?我宁愿不必诉诸于此:
[XmlRoot()]
public class Foo {
[XmlIgnore()]
public bool Bar { get; set; }
[XmlElement("Bar")]
public string BarXml { get { return (Bar) ? "yes" : "no"; } }
}
Run Code Online (Sandbox Code Playgroud)
请注意,我还希望能够再次反序列化此数据.
Blo*_*ard 22
好的,我一直在研究这个问题.这是我想出的:
// use this instead of a bool, and it will serialize to "yes" or "no"
// minimal example, not very robust
public struct YesNo : IXmlSerializable {
// we're just wrapping a bool
private bool Value;
// allow implicit casts to/from bool
public static implicit operator bool(YesNo yn) {
return yn.Value;
}
public static implicit operator YesNo(bool b) {
return new YesNo() {Value = b};
}
// implement IXmlSerializable
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader) {
Value = (reader.ReadElementContentAsString() == "yes");
}
public void WriteXml(XmlWriter writer) {
writer.WriteString((Value) ? "yes" : "no");
}
}
Run Code Online (Sandbox Code Playgroud)
然后我将我的Foo类更改为:
[XmlRoot()]
public class Foo {
public YesNo Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
请注意,因为YesNo可以隐式转换为bool(反之亦然),您仍然可以执行此操作:
Foo foo = new Foo() { Bar = true; };
if ( foo.Bar ) {
// ... etc
Run Code Online (Sandbox Code Playgroud)
换句话说,你可以像对待bool一样对待它.
而且!它序列化为:
<Foo><Bar>yes</Bar></Foo>
Run Code Online (Sandbox Code Playgroud)
它也正确地反序列化.
可能有一些方法可以让我的XmlSerializer自动将bool它遇到的任何s转换为YesNos - 但我还没有找到它.任何人?
非常简单.使用代理财产.在实际属性上应用XmlIgnore.代理是一个字符串,必须使用带有元素名称覆盖的XmlElement属性.指定覆盖中实际属性的名称.代理属性根据实际属性的值进行不同的序列化.您还必须为Surrogate提供一个setter,并且setter应该适当地设置实际属性,无论它序列化什么值.换句话说,它需要双向进行.
剪断:
public class SomeType
{
[XmlElement]
public int IntValue;
[XmlIgnore]
public bool Value;
[XmlElement("Value")]
public string Value_Surrogate {
get { return (Value)? "Yes, definitely!":"Absolutely NOT!"; }
set { Value= (value=="Yes, definitely!"); }
}
}
Run Code Online (Sandbox Code Playgroud)
单击此处获取完整的可编译源示例.