Сериализация XML и пустые коллекции - PullRequest
3 голосов
/ 16 сентября 2008

У меня есть свойство, определенное как:

[XmlArray("delete", IsNullable = true)]
[XmlArrayItem("contact", typeof(ContactEvent)),
 XmlArrayItem("sms", typeof(SmsEvent))]
public List<Event> Delete { get; set; }

Если в списке <> Удалить нет элементов

<delete />

испускается. Если для List <> Delete установлено значение null

<delete xsi:nil="true" />

испускается. Есть ли способ использовать атрибуты, чтобы удалить элемент delete, если в коллекции нет элементов?

Грег - Отлично, я даже не читал документацию IsNullable, просто предполагал, что она сигнализирует об этом как о не нужной.

Роб Купер - Я пытался избежать ISerializable, но предложение Грегса работает. Я столкнулся с проблемой, которую вы описали в (1), я сломал кучу кода, просто возвратив ноль, если коллекция была нулевой длины. Чтобы обойти это, я создал класс EventsBuilder (класс, который я сериализирую, называется Events), который управлял всем временем жизни / созданием базовых объектов класса Events, который выплевывает классы Events для сериализации.

Ответы [ 4 ]

17 голосов
/ 01 мая 2009

У меня была та же проблема, когда я не хотел выводить элемент, если поле пустое или 0. Вывод XML не может использовать xsi: null = "true" (по замыслу).

Я где-то читал, что если вы включите свойство типа bool с тем же именем, что и поле, которым вы хотите управлять, но с добавлением 'Specified', XMLSerializer проверит возвращаемое значение этого свойства, чтобы определить, соответствует ли поле должно быть включено.

Чтобы добиться этого без реализации IXMLSerializer:

public List<Event> Delete { get; set; }
[XMLIgnore]
public bool DeleteSpecified
{
 get
 {
   bool isRendered = false;
   if (Delete != null)
   {
     isRendered = (Delete.Count > 0);
   } 

   return isRendered;
 }
 set
 {
 }
}
6 голосов
/ 16 сентября 2008

Если вы установите IsNullable = false или просто удалите его (по умолчанию это false), то элемент «delete» не будет выдан. Это будет работать, только если коллекция равна нулю.

Я предполагаю, что существует путаница между "обнуляемостью" в терминах .NET и тем, что относится к обнуляемым элементам в XML - тем, которые помечены атрибутом xml: nil. Свойство XmlArrayAttribute.IsNullable контролирует последнее.

1 голос
/ 16 сентября 2008

Прежде всего, я бы сказал, спросите себя " Что такое сериализация? ".

XmlSerializer делает именно то, что должен, сохраняя текущее состояние объекта в XML. Теперь я не уверен, почему текущее поведение не является «правильным» для вас, так как если вы инициализировали список, то он инициализируется .

Я думаю, у вас есть три варианта:

  1. Добавьте код в Getter, чтобы он возвращал ноль, если в коллекции 0 элементов. Это может испортить другой код, который у вас есть.
  2. Реализация интерфейса IXmlSerializable и выполнение всей работы самостоятельно.
  3. Если это обычный процесс, вы можете посмотреть на мой вопрос " Сериализация XML и унаследованные типы " - да, я знаю, что он имеет дело с другой проблемой, но показывает, как создать универсальный промежуточный класс сериализации, который затем можно «прикрепить», чтобы обеспечить инкапсуляцию процесса сериализации. Вы можете создать аналогичный класс, чтобы справиться с переопределением процесса по умолчанию для коллекций с нулевым / нулевым элементом.

Надеюсь, это поможет.

0 голосов
/ 16 сентября 2008

Вы всегда можете реализовать IXmlSerializer и выполнить сериализацию вручную.

См. http://www.codeproject.com/KB/cs/IXmlSerializable.aspx для примера.

...