完全に刷新された答え:
以前はXmlWriterをお勧めしましたが、それは不可能であることがわかりました。
XElement
私が思ったようにタイプを保存しなかったので、私はこの答えを編集しています。
var x = new XElement("element", true);
x.WriteTo(new XmlTextWriter(Console.Out)); // Write stuff to console using XmlTextWriter
WriteValue(Boolean)
が呼び出されることはなく、値はのように保存されXText
ますXElement
。
興味のある方は、XElement.WriteToがXmlWriter.WriteElement(拡張メソッド)を呼び出し、XmlWriter.WriteStringがXmlWriter.WriteStringを呼び出します。
XmlWriter.WriteStringの動作を変更することは可能ですが、それによって
var x = new XElement("element", "true"); // String instead of bool
タイプが保存されていないためです。
私の解決策は、ファクトリを作成し、それを介してXElementsの作成方法を制御することです。IE:
class XElementFactory {
public static XElement CreateXElement(string name, object value) {
var type = obj.GetType();
if (typeof(boolean).Equals(type))
// Format the XText accordig to specification, use the XText ctor for clarification and readability
return new XElement(name, (bool) obj ? new XText("True") : XText("False"));
// Maybe add additional if clauses if there are just a few special cases
return new XElement(name, obj); // Let it through
}
}
リフレクションはパフォーマンスに深刻な打撃を与えますが、XMLを扱っているので、最初からパフォーマンスはそれほど重要ではないと思います。必要に応じて、タイプに応じて正しいビルダーが呼び出されるビルダーパターンを使用します。つまり、次のようなものを使用します。
Builders.First(b => b.Types.Contains(objToBuild.GetType())).BuildXElement(objToBuild); // Builders could maybe be filled by MEF?
この答えは少し長くなりました(しかし、私は長い電話会議= Pの間に何かをしました)、そして本質的に問題はフォーマットの問題ではなく作成の問題であることが判明しました。