nil="true"
type のプロパティを持つクラスにマークできる要素を含む XML メッセージをデシリアライズしたいと考えていましたint?
。それを機能させる唯一の方法は、NullableInt
実装する独自の型を作成することでしたIXmlSerializable
。それを行うより良い方法はありますか?
問題の全容と解決方法をブログに書きました。
nil="true"
type のプロパティを持つクラスにマークできる要素を含む XML メッセージをデシリアライズしたいと考えていましたint?
。それを機能させる唯一の方法は、NullableInt
実装する独自の型を作成することでしたIXmlSerializable
。それを行うより良い方法はありますか?
問題の全容と解決方法をブログに書きました。
XmlSerializer が null にデシリアライズするには、nil="true" の前に名前空間を付ける必要があると思います。
<?xml version="1.0" encoding="UTF-8"?>
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="array">
<entity>
<id xsi:type="integer">1</id>
<name>Foo</name>
<parent-id xsi:type="integer" xsi:nil="true"/>
私の修正は、ノードを前処理して、「nil」属性を修正することです。
public static void FixNilAttributeName(this XmlNode @this)
{
XmlAttribute nilAttribute = @this.Attributes["nil"];
if (nilAttribute == null)
{
return;
}
XmlAttribute newNil = @this.OwnerDocument.CreateAttribute("xsi", "nil", "http://www.w3.org/2001/XMLSchema-instance");
newNil.Value = nilAttribute.Value;
@this.Attributes.Remove(nilAttribute);
@this.Attributes.Append(newNil);
}
これを子ノードの再帰的検索と組み合わせて、特定の XmlNode (または XmlDocument) に対して、逆シリアル化の前に単一の呼び出しを発行できるようにします。元のメモリ内構造を変更せずに保持する場合は、XmlNode の Clone() を使用します。
それを行うための非常に怠惰な方法。いくつかの理由で壊れやすいのですが、私の XML は単純なので、このような迅速で汚い修正が必要になります。
xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"");