質問
次のように定義されたプロパティがあります。
[XmlArray("delete", IsNullable = true)]
[XmlArrayItem("contact", typeof(ContactEvent)),
XmlArrayItem("sms", typeof(SmsEvent))]
public List<Event> Delete { get; set; }
List<> Delete に項目がない場合
<delete />
が発せられる。List<> Delete が null に設定されている場合
<delete xsi:nil="true" />
が発せられる。属性を使用して、コレクションに項目がない場合に削除要素が出力されないようにする方法はありますか?
グレッグ - 完璧に感謝します。私は IsNullable のドキュメントすら読んでいませんでしたが、それが不要であることを示していると思っていました。
ロブ・クーパー - ISerializable を避けようとしましたが、Gregs の提案は機能します。(1)で概説した問題に遭遇しました。コレクションの長さがゼロの場合にnullを返すだけで、多くのコードを壊してしまいました。これを回避するために、私は EventsBuilder クラス (シリアル化しているクラスは Events と呼ばれます) を作成しました。このクラスは、シリアル化のために Events クラスを吐き出す Events クラスの基礎となるオブジェクトの有効期間/作成をすべて管理します。
解決
IsNullable=false を設定するか、単に削除した場合 (デフォルトでは false)、「delete」要素は出力されません。これは、コレクションが null に等しい場合にのみ機能します。
私の推測では、.NET の「null 許容性」と、XML の null 許容要素 (xml:nil 属性でマークされた要素) に関連するものとの間に混乱があるのではないかと考えられます。XmlArrayAttribute.IsNullable プロパティは後者を制御します。
他のヒント
フィールドが空または0の場合に要素を出力したくないという同じ問題が発生しました。出力された XML では、xsi:null="true" を使用できませんでした (仕様上)。
制御したいフィールドと同じ名前で「Specified」が付加された bool 型のプロパティを含めると、XMLSerializer はこのプロパティの戻り値をチェックして、対応するフィールドを含まれています。
IXMLSerializer を実装せずにこれを実現するには:
public List<Event> Delete { get; set; }
[XMLIgnore]
public bool DeleteSpecified
{
get
{
bool isRendered = false;
if (Delete != null)
{
isRendered = (Delete.Count > 0);
}
return isRendered;
}
set
{
}
}
まず最初に、自分自身に問いかけてみてください。」シリアル化とは何ですか?".
の Xmlシリアライザー は、オブジェクトの現在の状態を XML に永続化し、本来の動作を正確に実行しています。さて、現在の動作がなぜあなたにとって「正しく」ないのかはわかりません。リストを初期化した場合、それは は 初期化された。
ここには 3 つの選択肢があると思います。
- コレクションに項目が 0 個ある場合に null を返すコードを Getter に追加します。ただし、これにより、他のコードが台無しになる可能性があります。
- を実装します。 IXmlSerializable インターフェイスを作成し、すべての作業を自分で行います。
- これが一般的なプロセスである場合は、私の質問を参照してください。XML シリアル化と継承された型" - はい、別の問題を扱っていることはわかっていますが、シリアル化プロセスをカプセル化できるように「追加」できる汎用の中間シリアル化クラスを作成する方法を示しています。null/ゼロ項目コレクションのデフォルト プロセスのオーバーライドに対処する同様のクラスを作成できます。
これがお役に立てば幸いです。
いつでも IXmlSerializer を実装し、シリアル化を手動で実行できます。
見る http://www.codeproject.com/KB/cs/IXmlSerializable.aspx たとえば。