2010-07-16 10 views
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 

जब मैं ऊपर वर्ग के उदाहरण को क्रमानुसार, इस के रूप में, बनाया एक्सएमएल इस तरह दिखता है:

<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) 

मैं जो मैं एक नाम के साथ लैस कर सकता है स्ट्रिंग से विरासत में मिली एक कस्टम वर्ग, के लिए तार का बदलने की कोशिश करना चाहता था, लेकिन समस्या यह है कि कोई स्ट्रिंग से उत्तराधिकारी नहीं हो सकता है ...

उत्तर

0

आप शब्दकोश टेम्पलेट का विशेषज्ञ हो सकते हैं या एक विशेषज्ञता से प्राप्त कर सकते हैं जैसा आप चाहते हैं। कुछ इस तरह के

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

:

1

मैं सही ढंग से अपने प्रश्न पढ़ रहा हूँ, तो आप इस से अपने धारावाहिक उत्पादन बदलना चाहते

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

तुम भी उल्लेख है कि एक तरह से आप कर सकते थे यह प्राप्त करने के लिए अपना खुद का प्रकार बनाना होगा जो System.String से विरासत में मिला है, जैसा कि आप भी उल्लेख करते हैं - स्पष्ट रूप से संभव नहीं है क्योंकि यह sealed है।

डिफ़ॉल्ट रूप से, XmlSerializer को धारावाहिक:

आप लेकिन अपने स्वयं के प्रकार में महत्वपूर्ण मूल्य encapsulating, और उसके बाद को नियंत्रित करने का उपयोग कर एक XmlTextAttribute (MSDN देखें) XmlSerializer उत्पादन से एक ही परिणाम प्राप्त कर सकते हैं एक्सएमएल तत्व के रूप में एक वर्ग सदस्य। हालांकि, यदि आप किसी सदस्य को XmlTextAttribute लागू करते हैं, तो XmlSerializer XML मान में इसके मान का अनुवाद करता है। इसका मतलब है कि मान की सामग्री में एन्कोड किया गया है जो एक XML तत्व है।

अपने मामले में आप इस प्रकार विशेषता का उपयोग करेंगे:

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

और फिर कुंजी (रों) अपने Dictionary के रूप में इस प्रकार का उपयोग करें। जो आप चाहते हैं उसे प्राप्त करना चाहिए।

0

हालांकि यह शायद कुछ हद तक विषय से दूर है, मुझे यह पूछने की ज़रूरत है कि एक्सएमएल का उपयोग इसे क्रमबद्ध करने के लिए क्यों करें? यदि आप भविष्य के लिए ऑब्जेक्ट स्टेटस को सहेजना चाहते हैं तो मैं एक्सएमएल के बजाय JSON का सुझाव दूंगा।

एक बड़ा लाभ यह है कि आप किसी भी विशेष कोड को बिना किसी विशेष कोड को आसानी से सहेज सकते हैं। पेलोड जेएसओएन के रूप में भी बहुत छोटा है, इसलिए यदि आवश्यक हो तो तार में भेजने के लिए यह एक शानदार प्रारूप है।

स्कॉट ग के पास जावास्क्रिप्टसेरियलाइज़र here का उपयोग करने के बारे में कुछ जानकारी है। मैं इसे ऑब्जेक्ट पर विस्तार विधि बनाने का सुझाव दूंगा। फिर आप यह कर सकते हैं:

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

यदि यह मेरी दिलचस्पी है तो मुझे बताएं और मैं विस्तार विधियों के लिए कोड पोस्ट कर सकता हूं। (काम पर नहीं है और मेरे पास उनके साथ नहीं है।)

+0

पहले, मैं .NET 2.0 तक ही सीमित कर रहा हूँ, और दूसरा, मुख्य समस्या यह है कि शब्दकोश एक सामान्य प्रकार और नहीं Serializable (JSON में नहीं या तो) है। मैं एक्सएमएल को क्रमबद्ध कर रहा हूं क्योंकि एक्सएमएल व्यापक रूप से उपयोग किया जाता है, और पढ़ने के लिए बेहतर है, अगर .NET 2.0 से क्रमबद्ध है। –

0

चूंकि आपके पास स्रोत है, इसलिए आप इसे संशोधित कर सकते हैं ताकि यह मौजूद होने पर एक्सएमएल विशेषताओं को देख सके। एक्सएमएल एट्रिब्योर परिवार के बारे में पवित्र नहीं है - यह किसी भी अन्य अटारी की तरह है जिसे प्रतिबिंब के माध्यम से देखा जा सकता है। एक बार आपके पास यह है कि आप कोड में नए नाम डाल सकते हैं जहां निर्माता और/या एक्सएमएल टैग पढ़ता है। आप टैग नामों को स्पष्ट रूप से ओवरराइड करने के लिए 2 पैरा जोड़ सकते हैं, जैसे ReadXml (myReader, "टेबल्स", "टेबल") और डिफ़ॉल्ट रूप से इन नामों का पालन करने के लिए कोड को बदलें। हालांकि सी # पर स्विच करने के लिए मिला :-)

0

कुंजीपटल चयन के साथ शब्दकोश को बदलने पर विचार करें। यह एक सूची के रूप में क्रमबद्ध है, नतीजतन यह छोटा है और एक्सएमएल नोड नाम cTable गुण/फ़ील्ड के नाम हैं।

[Serializable] 
[CollectionDataContract] 
public class TablesCollection : KeyedCollection<string, cTable> 
{ 
    protected override string GetKeyForItem(cTable item) 
    { 
     return item == null ? String.Empty : item.TableName; 
    } 
} 
0

एक अल्पज्ञात सार वर्ग जो पूरी तरह से serializeable है KeyedCollection कहा जाता है, कुंजी का समर्थन करता है नहीं कह सकता मैं का उपयोग किया है कि कि serializeable शब्दकोश के कार्यान्वयन, लेकिन मामले में आप नई चीजों की कोशिश करने को तैयार हैं, वहाँ है आधारित पहुंच, और आसानी से शब्दकोश के रूप में लागू किया जा सकता है।

.Net 2.0 Keyed Collection

संबंधित मुद्दे