Десериализация отдельных объектов - PullRequest
3 голосов
/ 31 марта 2011

Есть ли в .Net 4 способ легко десериализовать поток смешанных объектов один за другим?Я могу прочитать в начале элемента для объекта, который я хочу десериализовать, используя XmlTextReader.Read (), но попытался много способов десериализации этого конкретного объекта безуспешно.

Типы, которые я хочу десериализовать, могут быть прочитаны как список этих типов без проблем с помощью XmlSerializer, однако я хочу иметь возможность смешивать их, а не иметь входные файлы, содержащие только списки одного типа объекта.

например,

<Objects>
  <TypeA>...</TypeA>
  <TypeB>...</TypeB>
  <TypeA>...</TypeA>
  <TypeC>...</TypeC>
  ...
</Objects>

Порядок расположения объектов будет случайным.

Большое спасибо за любые указатели.

Я смотрел на XmlSerializer, DataContractSerializer и XElement, но не смог заставить их работать для этого (хотя я, возможно, не настроил их правильно, так как я не очень с ними знаком).

Ответы [ 3 ]

2 голосов
/ 31 марта 2011

Вы можете сделать это с помощью XmlSerializer.

Однако будьте осторожны со следующим:

  1. Массив, который вы сериализуете / десериализуете, должен быть объявлен как массив объекта ""(или базовый объект, если все другие типы наследуют его)
  2. К каждому типу будет прикреплен" xsi: type "
  3. Вы должны использовать [XmlInclude], чтобы включить все типы (s) вам когда-либо понадобится этот «корневой» объект.

Необходимость [XmlInclude] всех типов объектов означает, что вы не сможете динамически добавлять типы всериализации.Вам нужно будет добавить [XmlInclude] и перекомпилировать, чтобы включить новые типы.

Однако ваш XML станет:

<Objects>
  <TypeObj xsi:type="TypeA">...</TypeObj>
  <TypeObj xsi:type="TypeB">...</TypeObj>
  <TypeObj xsi:type="TypeA">...</TypeObj>
  <TypeObj xsi:type="TypeC">...</TypeObj>
      :
</Objects>

Это наиболее гибкийи «нормальный» способ подхода XML-сериализации нескольких типов.Однако, если вам нужно сохранить свой точный формат, вы можете объявить свой класс следующим образом:

[XmlRoot("Objects")]
public class Objects
{
    [XmlElement("TypeA")] public TypeA[] TypeAObjects;
    [XmlElement("TypeB")] public TypeB[] TypeBObjects;
    [XmlElement("TypeC")] public TypeC[] TypeCObjects;
         :
}

[XmlElement] означает, что все объекты перемешаны на одном уровне (отличается от XmlArray),Они даже не должны быть в порядке.

Однако, подводные камни в этом случае заключаются в том, что если вы хотите добавить новый тип, вам придется изменить класс "Objects".

0 голосов
/ 31 марта 2011

Вам нужно будет создать XmlSerializer для каждого типа. Сколько у вас типов и сколько раз каждый из них будет использоваться, определит, будет ли лучше создавать новый XmlSerializer для каждого объекта при его обработке или сохранять их в Dictionary<string, XmlSerializer> для повторного использования. XmlSerializer принимает type в своем конструкторе, и затем вы можете вызвать метод Deserialize, передав ему StringReader, который содержит XML-строку, которую вы прочитали из вашего файла. Надеюсь, этого достаточно, чтобы начать, но если вам понадобится дополнительная помощь, я могу собрать несколько примеров кода;)

0 голосов
/ 31 марта 2011

Не уверен, что это полезно, но, возможно, стоит взглянуть на то, как RestSharp выполняет их десериализацию.https://github.com/johnsheehan/RestSharp

Специально Посмотрите на RestSharp / Deserializer / XmlDeserializer.cs

...