Могу ли я не выполнить десериализацию с помощью XmlSerializer в C#, если элемент не найден?

Я использую XmlSerializer для записи и чтения объекта в xml на C#. В настоящее время я использую атрибуты XmlElement и XmlIgnore для управления сериализацией объекта.

Если в моем XML-файле отсутствует элемент xml, который мне нужен, мой объект все равно десериализуется (xml -> объект) нормально. Как мне указать (желательно с помощью атрибутов), что определенное поле является «обязательным»?

Вот пример того, что я использую в настоящее время:

[XmlElement(ElementName = "numberOfWidgets")]
public int NumberThatIsRequired {
    set ...;
    get ...;
}

Моим идеальным решением было бы добавить что-то вроде атрибута XmlRequired.

Кроме того, есть ли хорошая ссылка на то, какие атрибуты доступны для управления поведением XmlSerializer?

Аналогичный вопрос msdn здесь, который также объясняет, что проверка - это то, что вы пытаетесь сделать

KCD 08.02.2012 03:06

если у вас нет элемента numberOfWidgets в XML, что будет у вас в свойстве NumberThatIsRequired? нуль?

Louis Rhys 11.07.2012 14:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
14
2
13 237
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

У меня есть ответ на вторую часть: «Атрибуты, управляющие сериализацией XML».

Все еще исследуем первую часть ...

Обновлено: Я сильно подозреваю, что вы не можете сделать это через саму десериализацию XML. Я только что запустил xsd.exe на примере схемы, которая включает обязательный атрибут - и это будет точно так же, если атрибут отмечен как необязательный. Если бы существовал способ требовать установки свойств, я бы ожидал, что он будет реализован в этом случае.

Я подозреваю, что вам нужно просто проверить свое дерево объектов после его десериализации. Прости за это...

Вам необходимо правильно настроить пространство имен XML в исходном XML, на который также ссылается ваш XSD, иначе проверка с использованием XSD не будет работать должным образом, включая проверку обязательного поля.

Robert Harvey 03.05.2010 03:22

Я нашел единственный способ сделать это - через XSD. Что вы можете сделать, так это проверить во время десериализации:

static T Deserialize<T>(string xml, XmlSchemaSet schemas)
{
    //List<XmlSchemaException> exceptions = new List<XmlSchemaException>();
    ValidationEventHandler validationHandler = (s, e) =>
    {
        //you could alternatively catch all the exceptions
        //exceptions.Add(e.Exception);
        throw e.Exception;
    };

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.Schemas.Add(schemas);
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationEventHandler += validationHandler;

    XmlSerializer serializer = new XmlSerializer(typeof(T));
    using (StringReader sr = new StringReader(xml))
        using (XmlReader books = XmlReader.Create(sr, settings))
           return (T)serializer.Deserialize(books);
}

По причинам расширяемости XmlSerializer очень снисходителен к десериализации; такие вещи, как [DefaultValue], ShouldSerialize{Foo} и {Foo}Specified, являются в основном, используемыми во время сериализация (исключение составляет {Foo}Specified, который устанавливается во время десериализации, а также запрашивается во время сериализации).

Как таковой; нет простого способа сделать это, если вы не реализуете IXmlSerializable и не сделаете это сами. Damagednoob показывает опцию xsd, которая также является опцией.

DefaultValue имеет по крайней мере один важный эффект во время десериализации. Если элемент пустой, без DefaultValue может возникнуть ошибка синтаксического анализа. Однако при этом сгенерированный код пропустит пустой элемент.

Matthew Flaschen 07.07.2012 06:15

Другие вопросы по теме