I'm sending xml to another program, which expects boolean flags as "yes" or "no", rather than "true" or "false".
I have a class defined like:
[XmlRoot()]
public class Foo {
public bool Bar { get; set; }
}
When I serialize it, my output looks like this:
<Foo><Bar>true</Bar></Foo>
But I would like it to be this:
<Foo><Bar>yes</Bar></Foo>
Can I do this at the time of serialization? I would prefer not to have to resort to this:
[XmlRoot()]
public class Foo {
[XmlIgnore()]
public bool Bar { get; set; }
[XmlElement("Bar")]
public string BarXml { get { return (Bar) ? "yes" : "no"; } }
}
Note that I also want to be able to deserialize this data back again.
The XmlSerializer creates C# (. cs) files and compiles them into . dll files in the directory named by the TEMP environment variable; serialization occurs with those DLLs. These serialization assemblies can be generated in advance and signed by using the SGen.exe tool.
Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization.
Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance.
Ok, I've been looking into this some more. Here's what I've come up with:
// 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");
}
}
Then I change my Foo class to this:
[XmlRoot()]
public class Foo {
public YesNo Bar { get; set; }
}
Note that because YesNo
is implicitly castable to bool
(and vice versa), you can still do this:
Foo foo = new Foo() { Bar = true; };
if ( foo.Bar ) {
// ... etc
In other words, you can treat it like a bool.
And w00t! It serializes to this:
<Foo><Bar>yes</Bar></Foo>
It also deserializes correctly.
There is probably some way to get my XmlSerializer to automatically cast any bool
s it encounters to YesNo
s as it goes - but I haven't found it yet. Anyone?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With