Вопрос: Я использую сериализуемый класс словаря, найденный по http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx, для сериализации словаря. Который хорошо работает, но я сталкиваюсь с раздражающей проблемой.
_
Public Class cDataBase
_
Public ns As New System.Xml.Serialization.XmlSerializerNamespaces()
_
Public Tables1 As New SerializableDictionary(Of String, cTable)
End Class ' cDataBase
Когда я сериализирую экземпляры вышеупомянутого класса, поскольку это, созданный xml похож на это:
-
MyTable
Uniqueidentifier
36
- Reihe1
- Reihe2
- Reihe3
- Reihe1
- Reihe2
- Reihe3
Который был бы хорош, если только я мог бы выяснить, как переименовать ключ от <строки> до чего-то определенного в атрибуте
MyTable
В основном что-то как атрибут XmlArrayItem, такой как ниже, если (только) словарь был массивом...
_
_
Public Tables As New List(Of cTable)
Я хотел попробовать к изменению Строки к пользовательскому классу, наследованному от строки, которую я мог оборудовать именем, но проблема, нельзя наследоваться строке...
7
задан Stefan Steiger 16 July 2010 в 11:22
поделиться
6 ответов
Вы можете специализировать шаблон Dictionary или получить производную от специализации для сериализации, как вам нужно.
0
ответ дан 7 December 2019 в 20:33
поделиться
Если я правильно читаю ваш вопрос, вы хотите изменить свой сериализованный вывод следующим образом:
<Tables>
<item>
<key>
<string>MyTable</string>
</key>
<value>
<!-- snip -->
</value>
</item>
</Tables>
На что-то вроде этого:
<Tables>
<item>
<key>
<TableId>MyTable</TableId>
</key>
<value>
<!-- snip -->
</value>
</item>
</Tables>
Вы также упоминаете, что одним из способов добиться этого было бы создание собственного типа который унаследован от System.String
, что, как вы также упомянули, очевидно, невозможно, потому что оно запечатано
.
Вы можете достичь того же результата, инкапсулируя значение ключа в свой собственный тип, а затем управляя выводом XmlSerializer
с помощью XmlTextAttribute
(см. MSDN ):
По умолчанию XmlSerializer
сериализует член класса как XML
элемент. Однако если вы примените
XmlTextAttribute для члена,
XmlSerializer переводит свое значение
в текст XML. Это означает, что
значение закодировано в содержании
элемент XML.
В вашем случае вы должны использовать атрибут следующим образом:
public class TableId
{
[XmlText]
public string Name
{
get;
set;
}
}
А затем использовать этот тип в качестве ключа (ов) к вашему Словарю
. Который должен достичь того, чего вы хотите.
1
ответ дан 7 December 2019 в 20:33
поделиться
Поскольку у вас есть источник, вы можете изменить его, чтобы он выполнял поиск атрибутов XML, если они есть. В семействе атрибутов XML нет ничего сакрального - они такие же, как и любые другие атрибуты, которые можно найти с помощью отражения. Как только вы это сделаете, вы можете добавить новые имена в код, где он будет создавать и / или читать теги XML. Вы также можете просто добавить 2 параметра для явного переопределения имен тегов, например ReadXml (myReader, «Таблицы», «Таблица»), и изменить код, чтобы он следовал этим именам вместо значений по умолчанию. Однако нужно перейти на C #: -)
0
ответ дан 7 December 2019 в 20:33
поделиться
Хотя это, вероятно, несколько не по теме, я должен спросить, зачем использовать XML для его сериализации? Если вы просто хотите сохранить состояние объекта на будущее, я бы предложил JSON вместо XML.
Одним из больших преимуществ является то, что вы можете легко сохранить обычный класс Dictionary без необходимости писать какой-либо специальный код. Полезная нагрузка также намного меньше, чем JSON, поэтому при необходимости это отличный формат для отправки по сети.
У Скотта Гу есть небольшая информация об использовании JavascriptSerializer здесь . Я бы посоветовал сделать это методом расширения объекта. Затем вы можете сделать это:
Dictionary<int, string> myDict = new Dictionary<int,string>();
myDict.Add(10,"something");
string jsonData = myDict.ToJSON();
Если вас это интересует, дайте мне знать, и я могу опубликовать код для методов расширения, которые я использую. (извините, не на работе, а их здесь нет.)
0
ответ дан 7 December 2019 в 20:33
поделиться
Рассмотрите возможность замены 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;
}
}
0
ответ дан 7 December 2019 в 20:33
поделиться
не могу сказать, что я использовал эту реализацию сериализуемого словаря, но на случай, если вы захотите попробовать что-то новое, есть малоизвестный абстрактный класс под названием KeyedCollection, который полностью сериализуем, поддерживает доступ на основе ключей и может быть легко реализован в виде словаря.
0
ответ дан 7 December 2019 в 20:33
поделиться
Другие вопросы по тегам: Похожие вопросы: