2009-12-30 2 views
2

У меня есть класс, который мне нужен для выполнения пользовательского XML-вывода, поэтому я реализую интерфейс IXmlSerializable. Тем не менее, некоторые из полей, которые я хочу выводить, с сериализацией по умолчанию, за исключением того, что я хочу изменить имена тегов xml. Когда я вызываю serializer.Serialize, я получаю имена тегов по умолчанию в XML. Могу ли я их каким-то образом изменить?Пользовательская сериализация с использованием XmlSerializer

Вот мой код:

public class myClass: IXmlSerializable 
{ 
    //Some fields here that I do the custom serializing on 
    ... 

    // These fields I want the default serialization on except for tag names 
    public string[] BatchId { get; set; } 
    ... 

    ... ReadXml and GetSchema methods are here ... 

    public void WriteXml(XmlWriter writer) 
    {       
     XmlSerializer serializer = new XmlSerializer(typeof(string[])); 
     serializer.Serialize(writer, BatchId); 
     ... same for the other fields ... 

     // This method does my custom xml stuff 
     writeCustomXml(writer); 
    } 

    // My custom xml method is here and works fine 
    ... 
} 

Вот мой выход Xml:

<MyClass> 
    <ArrayOfString> 
     <string>2643-15-17</string> 
     <string>2642-15-17</string> 
     ... 
    </ArrayOfString> 
    ... My custom Xml that is correct .. 
    </MyClass> 

То, что я хочу, чтобы в конечном итоге это:

<MyClass> 
    <BatchId> 
     <id>2643-15-17</id> 
     <id>2642-15-17</id> 
     ... 
    </BatchId> 
    ... My custom Xml that is correct .. 
    </MyClass> 
+0

Как часто вы сериализации/десериализации? 100 раз в течение жизненного цикла приложения или только при запуске/завершении работы. Если первое, у меня есть реализация, которая значительно более гибкая. –

+0

Действительно только сериализация один раз. Это приложение представляет собой простой инструмент, который извлекает данные из проприетарного формата базы данных и сохраняет в xml. Поэтому я потянул данные в объектную модель, а затем сразу же сериализую. Большинство данных были простыми, поэтому мне не нужно было внедрять IXmlSerializable ... но эта конкретная часть данных была немного больной. – KrisTrip

+0

Ну, посмотрите здесь, код MIT http://code.google.com/p/videobrowser/source/browse/MediaBrowser/Library/Persistance/XmlSettings.cs есть также единичный тест, возможно, вам придется немного расширьте его, но вся архитектура есть. плюс для вашего сценария он будет выполнять MUCH лучше, чем XmlSerializer –

ответ

7

Во многих случаях, вы можете использовать XmlSerializer конструктор перегрузки, которая принимает XmlAttributeOverrides указать эту дополнительную информацию об имени (например, передавая новый XmlRootAttribute) - однако, это не работает для массивов AFAIK. Я ожидаю, что для примера string[] было бы проще просто написать его вручную. В большинстве случаев IXmlSerializable - это много дополнительной работы - я избегаю этого, насколько это возможно, по таким причинам. Сожалею.

+0

XmlSerializer - это старая часть неподготовленной, неэффективной технологии, которая должна была быть устаревшей от MS в давние времена или с минимальным минимальным переопределением. У меня были проблемы с этим. Лучше отключить использование буферов протокола: p –

+0

Как заманчиво это видеть, могу ли я закрутить вывод pb-net в xml ;-p –

+0

, вы должны это сделать полностью и сделать его подключаемым, чтобы люди могли реализовать свой собственный формат персистентности, затем вы даже можете использовать sqlite в качестве хранилища данных ... –

3

Вы можете пометить ваши поля с атрибутами до control the serialized XML. Например, добавление следующих атрибутов:

[XmlArray("BatchId")] 
[XmlArrayItem("id")] 
public string[] BatchId { get; set; } 

, вероятно, доставит вас туда.

+1

Пробовал это. Не повезло. – KrisTrip

0

Если кто-то все еще ищет это, вы можете определенно использовать XmlArrayItem, однако это должно быть свойство в классе.

Для удобства чтения вы должны использовать множественное число и единство одного и того же слова.

/// <summary> 
    /// Gets or sets the groups to which the computer is a member. 
    /// </summary> 
    [XmlArrayItem("Group")] 
    public SerializableStringCollection Groups 
    { 
     get { return _Groups; } 
     set { _Groups = value; } 
    } 
    private SerializableStringCollection _Groups = new SerializableStringCollection(); 



<Groups> 
    <Group>Test</Group> 
    <Group>Test2</Group> 
</Groups> 

Дэвид

Смежные вопросы