Пользовательская сериализация с использованием XmlSerializer

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

Вот мой код:

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>

person KrisTrip    schedule 30.12.2009    source источник
comment
Как часто вы сериализуете/десериализуете? Сотни раз в течение жизненного цикла приложения или только при запуске/выключении. Если первое, у меня есть реализация, которая значительно более гибкая.   -  person Sam Saffron    schedule 30.12.2009
comment
На самом деле только сериализация один раз. Это приложение представляет собой простой инструмент, который извлекает данные из проприетарного формата базы данных и сохраняет их в формате xml. Итак, я загружаю данные в объектную модель, а затем сразу же сериализую. Большая часть данных была простой, поэтому мне не нужно было реализовывать IXmlSerializable... но этот конкретный фрагмент данных был немного болезненным.   -  person KrisTrip    schedule 30.12.2009
comment
Взгляните сюда, код MIT code.google.com/p/videobrowser/source/browse/MediaBrowser/ также есть модульный тест, возможно, вам придется немного его расширить, но вся архитектура есть. плюс для вашего сценария он будет работать НАМНОГО лучше, чем XmlSerializer   -  person Sam Saffron    schedule 30.12.2009


Ответы (3)


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

person Marc Gravell    schedule 30.12.2009
comment
XmlSerializer — это старая часть неподдерживаемой, неэффективной технологии, которая должна была быть объявлена ​​устаревшей MS много лет назад или, как минимум, заново реализована. У меня были только проблемы с этим. Лучше использовать буферы протокола: p - person Sam Saffron; 30.12.2009
comment
Как заманчиво посмотреть, смогу ли я преобразовать вывод pb-net в xml ;-p - person Marc Gravell; 30.12.2009
comment
вы должны полностью это сделать и сделать его подключаемым, чтобы люди могли реализовать свой собственный формат сохранения, тогда вы даже можете использовать sqlite в качестве хранилища данных... - person Sam Saffron; 30.12.2009


Если кто-то все еще ищет это, вы определенно можете использовать 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>

Дэйвид

person David Homer    schedule 01.09.2016