#c# #xml #serialization #xml-serialization
#c# #xml #сериализация #xml-сериализация
Вопрос:
Мне нужно сериализовать объекты в XML в C #. Объекты должны быть завернуты в конверт. Для этого я создал следующий Envelope
класс:
[XmlInclude(typeof(Person))]
public class Envelope
{
public string SomeValue { get; set; }
public object WrappedObject { get; set; }
}
Я использую следующий код для сериализации класса:
string fileName = ...;
XmlSerializer serializer = new XmlSerializer(typeof(Envelope));
TextWriter textWriter = new StreamWriter(fileName);
try
{
serializer.Serialize(textWriter, <instance of envelope>);
}
finally
{
textWriter.Close();
}
Когда я присваиваю объекту типа Person
to WrappedObject
, я получаю следующий XML:
<Envelope>
<SomeValue>...</SomeValue>
<WrappedObject xsi:type="Person">
....
</WrappedObject>
</Envelope>
Проблема в том, что я хотел бы, чтобы тег для обернутого объекта был назван в честь фактического класса, в который я передаю. Например, если я назначу экземпляр Person
для WrappedObject
, я бы хотел, чтобы XML выглядел следующим образом:
<Envelope>
<SomeValue>...</SomeValue>
<Person>
....
</Person>
</Envelope>
Если я назначу экземпляр Animal
, я хотел бы получить
<Envelope>
<SomeValue>...</SomeValue>
<Animal>
....
</Animal>
</Envelope>
Как бы мне этого добиться?
Редактировать
На самом деле я немного упростил свой пример… Обернутый объект фактически снова оборачивается:
public class Envelope
{
public string SomeValue { get; set; }
public Wrapper Wrap { get; set; }
}
[XmlInclude(typeof(Person))]
public class Wrapper
{
public object WrappedObject { get; set; }
}
Как бы я справился с этим, используя переопределение атрибутов?
Ответ №1:
Вам нужно использовать переопределение атрибута. Я интенсивно использую его, поскольку выполняю множество пользовательских сериализаций.
Это грубый непроверенный фрагмент, но он должен указать вам правильное направление:
XmlAttributes attributes = new XmlAttributes();
XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides();
attributes.XmlElements.Add(new XmlElementAttribute("Person", t));
xmlAttributeOverrides.Add(typeof(Person), "WrappedObject", attributes);
XmlSerializer myserialiser = new XmlSerializer(typeof(Envelope), xmlAttributeOverrides);
Комментарии:
1. Хорошо, я вижу, как это работает, но я должен признать, что я немного упростил свой пример 😉 Не могли бы вы взглянуть на мою измененную версию выше?
2. Должен работать тот же код. Вам даже не понадобится
XmlInclude
3. Хм, когда я удаляю
XmlInclude
, я получаю исключение, в котором говорится что-то вроде «Неожиданный тип …, используйте XmlInclude или SoapInclude …».4. Хорошо, возможно, вы можете добавить,
XmlInclude
используяXmlAttributeOverrides
сам и сделать его аккуратнее.5. Упс, я скопировал / вставил ваш код, и после имени свойства есть дополнительный символ «Пробел»
WrappedObject
. Я случайно оставил это в. Когда я удаляю его, все работает так, как ожидалось! Большое вам спасибо!