Подтвердить что ты не робот

Десериализация переписей

У меня есть xml, в котором один из элементов имеет атрибут, который может быть пустым. Например,

<tests>
<test language="">
.....
</test>
</tests>

Теперь язык - это тип перечисления в классах, созданных из схемы. Он отлично работает, если язык указан, он не может десериализоваться, если он пуст (как показано в примере).

Изменить: Код для десериализации:

XmlSerializer xmlserializer = new XmlSerializer(type);
StringReader strreader = new StringReader(stringXML);
Object o = serializer.Deserialize(strreader);

Как я могу справиться с этим сценарием

4b9b3361

Ответ 1

Вы можете объявить свойство перечисления как nullable:

public Language? Language { get; set; }

Забастовкa >


EDIT: ОК, я просто попробовал, он не работает для атрибутов... Вот еще один вариант: не сериализуйте/десериализуйте это свойство напрямую, а сериализуйте свойство строки:

[XmlIgnore]
public Language Language { get; set; }

[XmlAttribute("Language")]
public string LanguageAsString
{
    get { return Language.ToString(); }
    set
    {
        if (string.IsNullOrEmpty(value))
        {
            Language = default(Language);
        }
        else
        {
            Language = (Language)Enum.Parse(typeof(Language), value);
        }
    }
}

Ответ 2

Вам, вероятно, нужно будет пометить свое перечисление и добавить элемент по умолчанию, который представляет Unknown.

Например:

Public Enum EmployeeStatus
   <XmlEnum("")> Unknown = 0
   <XmlEnum("Single")> One = 1
   <XmlEnum("Double")> Two = 2
   <XmlEnum("Triple")> Three = 3
End Enum

Для получения дополнительной информации см. здесь.

Ответ 3

Вы можете сделать это следующим образом:

namespace Example
{

   public enum Language
   {
     [XmlEnum("en")]
     English,

     [XmlEnum("de")]
     Deutsch
   }

   public class ExampleClass
   {

      private Language? language;

      [XmlAttribute("Language")]
      public Language Language
      {
         get { return language ?? Example.Language.English; }
         set { language = value; }
      }

      .
      .
      .
   }
}

Ответ 4

Что бы вы хотели получить?

Пустое значение не может быть сопоставлено с нулевой ссылкой, поскольку перечисление является типом значения, не имеющим значения NULL.

Ответ 5

object wontBeNull = couldBeNull ?? defaultIfNull;

Я бы попробовал. Он называется Оператор Null-Coalescing, я использую его, когда я хочу по умолчанию для ввода с нулевым значением.

Ответ 6

@genericuser

(* Я использую LinqPad для проверки этого, поэтому вы можете увидеть вызов .Dump() в конце моего примера)

В моем коде, следуя инструкциям в лучшем ответе здесь, я пытаюсь присвоить значение (claves_sexo) ND = 2 для Product.Sexo, пока тег пуст, но он всегда назначает первое значение для перечисление (HO = 0).

Я ожидал, что включенный член, помеченный атрибутом [XmlAttribute ("Sexo")] SexoAsString, заменит значение для члена Sexo, но отладчик показывает мне, что он никогда не достигает своего установщика.

Можете ли вы помочь мне достичь этого? Если в обрабатываемом XML тег sexo пуст, происходит сбой...

Заранее спасибо,

Роджер

void Main()
{
    string xmlString = "<Products><Product><Id>1</Id><Name>My XML product</Name><Sexo></Sexo></Product></Products>";    
    XmlSerializer serializer = new XmlSerializer(typeof(List<Product>), new XmlRootAttribute("Products"));
    StringReader stringReader = new StringReader(xmlString);
    List<Product> productList = (List<Product>)serializer.Deserialize(stringReader);
    productList.Dump();
}

public enum claves_sexo
{
    HO,
    MU,
    ND
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    [XmlIgnore]
    public claves_sexo Sexo {get;set;}

    [XmlAttribute("Sexo")]
    public string SexoAsString
    {
        get
        {
            return Sexo.ToString();
        }
        set
        {
            if (string.IsNullOrEmpty(value))
            {
                Sexo = claves_sexo.ND;
            }
            else
            {
                Sexo = (claves_sexo)int.Parse(value);
            }
        }
    }

}