可序列化字典,如何设置键名?
问题:我使用可序列化的字典类,位于 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>
如果我能弄清楚如何重命名密钥,那就太好了 <字符串>属性中定义的内容
<key>
<string>MyTable</string>
</key>
基本上类似于 XmlArrayItem 属性,如下所示,如果(仅)字典是一个数组...
<System.Xml.Serialization.XmlArray("Tables")> _
<System.Xml.Serialization.XmlArrayItem("Table")> _
Public Tables As New List(Of cTable)
我想尝试将 String 更改为从 string 继承的自定义类,我可以配备它一个名称,但问题是,不能从字符串继承......
Question: I use a serializable dictionary class, found at
http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx
, to serialize a dictionary.
Which works fine, but I run into an annoying problem.
<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
When I serialize instances of the above class, as this,
the created xml looks like this:
<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>
Which would be good if only I could figure out how to rename the key from
<string> to something defined in an attribute
<key>
<string>MyTable</string>
</key>
Basically something like the XmlArrayItem attribute, such as below, if (only) the dictionary were an array...
<System.Xml.Serialization.XmlArray("Tables")> _
<System.Xml.Serialization.XmlArrayItem("Table")> _
Public Tables As New List(Of cTable)
I wanted to try to change Of String to a custom class inherited from string, which I could equip with a name, but the problem is, one cannot inherit from string...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以专门化字典模板或从专门化派生以根据需要进行序列化。
You could specialize the Dictionary template or derive from a specialization to serialize as you want.
虽然这可能有点偏离主题,但我需要问为什么使用 XML 来序列化它?如果您只想保存对象状态以供将来使用,我建议使用 JSON 而不是 XML。
一大好处是您可以轻松保存普通的 Dictionary 类,而无需编写任何特殊代码。有效负载也比 JSON 小得多,因此它是一种在需要时通过网络发送的绝佳格式。
Scott Gu 有一些关于使用 JavascriptSerializer 的信息 此处。我建议将其作为对象的扩展方法。然后您可以这样做:
如果您对此感兴趣,请告诉我,我可以发布我使用的扩展方法的代码。 (抱歉,我不在工作,我也没有带它们。)
Although it's probably somewhat off topic, I need to ask why use XML to serialize it? If you just want to save the object state for the future I would suggest JSON instead of XML.
One large benefit is you can easily save a normal Dictionary class without having to write any special code. The payload is also much smaller as JSON so it's a great format to send across the wire if needed.
Scott Gu has a bit of info about using the JavascriptSerializer here. I would suggest making it an extension method on object. Then you can do this:
If this is something your interested in let me know and I can post the code for the extension methods I use. (sry not at work and I don't have them with me here.)
由于您拥有源代码,因此您可以修改它,以便它查找 XML 属性(如果存在)。 XML 属性家族没有什么特别之处——它们就像任何其他可以通过反射查找的属性一样。一旦你有了这个,你就可以将新名称放入创建者的代码中和/或读取 XML 标签。您还可以仅添加 2 个参数来显式覆盖标记名称,例如 ReadXml(myReader, "Tables", "Table") 并更改代码以遵循这些名称而不是默认值。不过必须切换到 C# :-)
Since you have the source you can modify it so that it looks up XML attributes if they are present. There's nothign sacral about XML attribure family - the are just like any other attrib that can be looked up via reflection. Once yo u have that you can put new names into the code where in creater and/or reads XML tags. You can also just add 2 params to override tag names explicitly, like ReadXml(myReader, "Tables", "Table") and change the code to follow these names instead of defaults. Got to switch to C# though :-)
考虑用 KeyedCollection 替换 Dictionary。它被序列化为列表,因此它更小,并且 XML 节点名称是 cTable 属性/字段的名称。
Consider replacing Dictionary with KeyedCollection. It is serialized as a list, as a result it is smaller and XML node names are names of cTable properties/fields.
不能说我已经使用了可序列化字典的实现,但是如果您愿意尝试新事物,有一个鲜为人知的抽象类,称为 KeyedCollection,它是完全可序列化的,支持基于键的访问,并且可以轻松地作为字典实现。
.Net 2.0 键控集合
can't say that i've used that implementation of serializeable dictionary, but in case you're willing to try new things, there is a little known abstract class called KeyedCollection which is fully serializeable, supports key based access, and can be easily implemented as dictionary.
.Net 2.0 Keyed Collection
如果我正确地阅读您的问题,您希望将序列化输出从以下位置更改为:
更改为这样的内容:
您还提到实现此目的的一种方法是创建自己的类型,该类型继承自
System.String
,正如您也提到的那样,这显然是不可能的,因为它是密封的
。不过,您可以通过将键值封装在您自己的类型中,然后使用
XmlTextAttribute
控制XmlSerializer
输出来实现相同的结果(请参阅< a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmltextattribute.aspx" rel="nofollow noreferrer">MSDN):在您的情况下,您将按如下方式使用该属性:
然后使用此类型作为
Dictionary
的键。这应该能达到你想要的效果。If I'm reading your question correctly, you want to change your serialized output from this:
To something like this:
You also mention that one way you could achieve this would be to create your own type which inherited from
System.String
, which - as you also mention - obviously isn't possible because it'ssealed
.You can however achieve the same result by encapsulating the key value in your own type, and then controlling the
XmlSerializer
output using anXmlTextAttribute
(see MSDN):In your case you'd use the attribute as follows:
And then use this type as the key(s) to your
Dictionary
. Which should achieve what you want.