我将xml发送到另一个程序,该程序期望布尔标志为“是”或“否”,而不是“真”或“假”。
我有一个类的定义如下:
[XmlRoot()]
public class Foo {
public bool Bar { get; set; }
}序列化它时,我的输出如下所示:
<Foo><Bar>true</Bar></Foo>但我希望是这样:
<Foo><Bar>yes</Bar></Foo>我可以在序列化时这样做吗?我宁愿不用这样做:
[XmlRoot()]
public class Foo {
[XmlIgnore()]
public bool Bar { get; set; }
[XmlElement("Bar")]
public string BarXml { get { return (Bar) ? "yes" : "no"; } }
}请注意,我还希望能够再次反序列化这些数据。
发布于 2009-03-09 08:51:16
好吧,我一直在调查这件事。以下是我想出的:
// 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");
}
}然后我把我的Foo类改为:
[XmlRoot()]
public class Foo {
public YesNo Bar { get; set; }
}注意,由于YesNo对bool是隐式的(反之亦然),您仍然可以这样做:
Foo foo = new Foo() { Bar = true; };
if ( foo.Bar ) {
// ... etc换句话说,你可以把它当作一个傻瓜。
还有w00t!它将序列化为:
<Foo><Bar>yes</Bar></Foo>它也正确地反序列化。
可能有一些方法可以让我的XmlSerializer自动将它遇到的任何bool转换为YesNo,但我还没有找到它。有没有人?
发布于 2009-03-09 05:37:28
非常简单。使用代理项属性。在实际属性上应用XmlIgnore。代理项是一个字符串,必须使用接受元素名称覆盖的XmlElement属性。指定重写中实际属性的名称。代理项属性根据实际属性值以不同的方式序列化。您还必须为代理程序提供一个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!"); }
}
}点击这里获取完全可编译源示例。
发布于 2009-03-09 05:18:50
将bool值序列化为"yes“或"no”将数据类型从根本上改变为布尔值。相反,您是否可以添加一个单独的属性来计算布尔值,并根据其数据类型返回“是”或“否”?您甚至可以通过使返回类型成为仅指定这些值的枚举来强制“是”或“否”。
public YesOrNo DoYouLoveIt
{
get { return boolToEvaluate ? YesOrNo.Yes : YesOrNo.No; }
}这可能有点过分,但可能会满足你的需要。我为这样一个简单的值提出一个枚举的唯一原因是,您将限制值而不是允许任何字符串。
https://stackoverflow.com/questions/625091
复制相似问题