7

質問: http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx にあるシリアライズ可能なディクショナリ クラスを使用して、ディクショナリをシリアライズしています。これは問題なく動作しますが、厄介な問題が発生します。

      <System.Xml.Serialization.XmlRoot("DataBase")> _
    Public Class cDataBase
        <System.Xml.Serialization.XmlNamespaceDeclarations()> _
        Public ns As New System.Xml.Serialization.XmlSerializerNamespaces()


        <System.Xml.Serialization.XmlElement("Tables")> _
        Public Tables1 As New SerializableDictionary(Of String, cTable)


    End Class ' cDataBase

上記のクラスのインスタンスをシリアル化すると、作成された xml は次のようになります。

<Tables>
<item>
  <key>
    <string>MyTable</string>
  </key>
  <value>
    <Table CreationDate="0001-01-01T00:00:00" LastModified="0001-01-01T00:00:00">
      <Columns>
        <Column Name="PrimaryKeyName">
          <DataType>Uniqueidentifier</DataType>
          <Length>36</Length>
        </Column>
      </Columns>
      <Rows>
        <Row>
          <Item>Reihe1</Item>
          <Item>Reihe2</Item>
          <Item>Reihe3</Item>
        </Row>
        <Row>
          <Item>Reihe1</Item>
          <Item>Reihe2</Item>
          <Item>Reihe3</Item>
        </Row>

キーの名前を <string> から属性で定義されたものに変更する方法を理解できれば、これは良いことです

  <key>
    <string>MyTable</string>
  </key>

(のみ) 辞書が配列である場合、基本的には以下のような XmlArrayItem 属性のようなもの...

        <System.Xml.Serialization.XmlArray("Tables")> _
        <System.Xml.Serialization.XmlArrayItem("Table")> _
        Public Tables As New List(Of cTable)

Of String を、名前を付けることができる、string から継承されたカスタム クラスに変更したかったのですが、問題は、string から継承できないことです...

4

6 に答える 6

1

あなたの質問を正しく読んでいる場合は、シリアル化された出力を次のように変更してください。

<Tables>
  <item>
    <key>
      <string>MyTable</string>
    </key>
    <value>
      <!-- snip -->
    </value>
  </item>
</Tables>

このようなものに:

<Tables>
  <item>
    <key>
      <TableId>MyTable</TableId>
    </key>
    <value>
      <!-- snip -->
    </value>
  </item>
</Tables>

また、これを達成できる1つの方法は、から継承した独自のタイプを作成することであると述べていますが、これは、あなたが言及しているようにSystem.Stringsealed.

ただし、キー値を独自の型にカプセル化し、次を使用して出力を制御することで、同じ結果を得ることができます( MSDNを参照)。XmlSerializerXmlTextAttribute

既定では、XmlSerializer はクラス メンバーを XML 要素としてシリアル化します。ただし、XmlTextAttribute をメンバーに適用すると、XmlSerializer はその値を XML テキストに変換します。これは、値が XML 要素のコンテンツにエンコードされることを意味します。

あなたの場合、次のように属性を使用します。

public class TableId
{
    [XmlText]
    public string Name
    {
        get;
        set;
    }
}

そして、このタイプをあなたのキーとして使用してくださいDictionary。あなたが望むものを達成する必要があります。

于 2010-07-28T12:34:39.567 に答える
0

ソースがあるので、それを変更して、存在する場合に XML 属性を検索することができます。XML 属性ファミリについては、特に問題はありません。これらは、リフレクションを介して検索できる他の属性とまったく同じです。それができたら、作成者および/またはXMLタグを読み取るコードに新しい名前を入れることができます。ReadXml(myReader, "Tables", "Table") のように、2 つのパラメーターを追加してタグ名を明示的にオーバーライドし、デフォルトではなくこれらの名前に従うようにコードを変更することもできます。ただし、C#に切り替える必要があります:-)

于 2010-08-03T06:52:58.147 に答える
0

シリアライズ可能なディクショナリの実装を使用したとは言えませんが、新しいことを試してみたい場合は、完全にシリアライズ可能で、キーベースのアクセスをサポートし、簡単に使用できる KeyedCollection というあまり知られていない抽象クラスがあります。辞書として実装されています。

.Net 2.0 キー付きコレクション

于 2010-08-07T22:15:21.603 に答える
0

Dictionary テンプレートを特殊化するか、特殊化から派生させて、必要に応じてシリアル化することができます。

于 2010-07-16T11:26:29.300 に答える
0

少々話が逸れるかもしれませんが、なぜ XML を使用してシリアル化するのかを尋ねる必要があります。将来のためにオブジェクトの状態を保存したいだけなら、XML ではなく JSON をお勧めします。

大きな利点の 1 つは、特別なコードを記述する必要なく、通常の Dictionary クラスを簡単に保存できることです。ペイロードも JSON よりはるかに小さいため、必要に応じてネットワーク経由で送信するのに適した形式です。

Scott Gu が、JavascriptSerializer の使用について少し情報を提供しています。オブジェクトの拡張メソッドにすることをお勧めします。次に、これを行うことができます:

Dictionary<int, string> myDict = new Dictionary<int,string>();
myDict.Add(10,"something");
string jsonData = myDict.ToJSON();

これに興味がある場合はお知らせください。私が使用している拡張メソッドのコードを投稿できます。(仕事ではないので、ここには持っていません。)

于 2010-07-30T05:44:38.803 に答える
0

Dictionary を KeyedCollection に置き換えることを検討してください。リストとしてシリアル化されるため、サイズが小さくなり、XML ノード名は cTable プロパティ/フィールドの名前になります。

[Serializable]
[CollectionDataContract]
public class TablesCollection : KeyedCollection<string, cTable>
{
    protected override string GetKeyForItem(cTable item)
    {
        return item == null ? String.Empty : item.TableName;
    } 
}
于 2010-08-03T08:16:38.277 に答える