[解決済み] IXmlSerializableの正しい実装方法?
質問
プログラマーが
IXmlSerializable
それを実装するためのルールやベストプラクティスは何でしょうか?という話を聞いたことがあります。
GetSchema()
を返すべき
null
と
ReadXml
は、次の要素に移動してから戻るべきです。これは本当でしょうか?また
WriteXml
- は、オブジェクトのルート要素を書くべきでしょうか、それともルートはすでに書かれていると仮定されるのでしょうか?子オブジェクトはどのように扱われ、どのように記述されるべきでしょうか?
今あるサンプルはこんな感じです。良い反応があれば更新していきます。
public class MyCalendar : IXmlSerializable
{
private string _name;
private bool _enabled;
private Color _color;
private List<MyEvent> _events = new List<MyEvent>();
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader)
{
if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyCalendar")
{
_name = reader["Name"];
_enabled = Boolean.Parse(reader["Enabled"]);
_color = Color.FromArgb(Int32.Parse(reader["Color"]));
if (reader.ReadToDescendant("MyEvent"))
{
while (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyEvent")
{
MyEvent evt = new MyEvent();
evt.ReadXml(reader);
_events.Add(evt);
}
}
reader.Read();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Name", _name);
writer.WriteAttributeString("Enabled", _enabled.ToString());
writer.WriteAttributeString("Color", _color.ToArgb().ToString());
foreach (MyEvent evt in _events)
{
writer.WriteStartElement("MyEvent");
evt.WriteXml(writer);
writer.WriteEndElement();
}
}
}
public class MyEvent : IXmlSerializable
{
private string _title;
private DateTime _start;
private DateTime _stop;
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader)
{
if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyEvent")
{
_title = reader["Title"];
_start = DateTime.FromBinary(Int64.Parse(reader["Start"]));
_stop = DateTime.FromBinary(Int64.Parse(reader["Stop"]));
reader.Read();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Title", _title);
writer.WriteAttributeString("Start", _start.ToBinary().ToString());
writer.WriteAttributeString("Stop", _stop.ToBinary().ToString());
}
}
対応するサンプルXML
<MyCalendar Name="Master Plan" Enabled="True" Color="-14069085">
<MyEvent Title="Write Code" Start="-8589241828854775808" Stop="-8589241756854775808" />
<MyEvent Title="???" Start="-8589241828854775808" Stop="-8589241756854775808" />
<MyEvent Title="Profit!" Start="-8589247048854775808" Stop="-8589246976854775808" />
</MyCalendar>
解決方法は?
はい、GetSchema() は null を返すべきです。 .
IXmlSerializable.GetSchema メソッド This メソッドは予約されているので、使用しないでください。 を使用します。を実装する場合 IXmlSerializable インターフェースでは、次のようにします。 はヌル参照(Nothing)を返します。 Visual Basic)の代わりにこのメソッドを使用します。 カスタムスキーマの指定が必要な場合 が必要な場合は XmlSchemaProviderAttributeを使用します。 クラスがあります。
read、writeともに、object要素はすでに書き込まれているので、writeで外側の要素を追加する必要はありません。例えば、2つの中で属性の読み書きを開始すればいいのです。
について 書く :
WriteXmlの実装は はXMLを書き出す必要があります。 オブジェクトの表現です。そのため フレームワークは、ラッパー要素を記述し は、XML ライターの後に配置されます。 を開始します。あなたの実装では その内容は、子 要素で構成されます。その後、フレームワークは ラッパー要素
そして 読む :
ReadXml メソッドは、以下のように再構築する必要があります。 の情報を使ってオブジェクトを作成します。 はWriteXmlメソッドによって書き込まれました。
このメソッドが呼ばれたとき、リーダー の開始位置に配置される。 の情報を包んでいる要素です。 を使用します。つまり 開始タグ を、シリアライズされたオブジェクトの この メソッドが返されたとき、それは 要素の最初から最後までの全体 そのすべての内容を含む。とは異なり フレームワークは、WriteXml メソッド は、ラッパー要素 を自動生成します。あなたの実装 が必要です。これらの の位置決めルールは、コードが 予期せぬ実行時例外の発生 またはデータが破損しています。
少し不明瞭な点には同意しますが、要するに "するのがあなたの仕事だということです。
Read()
ラッパー"の終了要素タグです。
関連
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み] .NETで文字列を改行で分割する最も簡単な方法とは?
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] IDisposable インターフェースの正しい使用法
-
[解決済み] イールドリターン」の正しい使い方
-
[解決済み] C#で文字を繰り返し表示する最適な方法
-
[解決済み] Entity Frameworkにおける最速の挿入方法
-
[解決済み] C# の辞書を値で初期化する適切な方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み】2つ(またはそれ以上)のリストを1つに統合する(C# .NETで
-
[解決済み】URLから画像をダウンロードする方法