Десериализация переписей
У меня есть xml, в котором один из элементов имеет атрибут, который может быть пустым.
Например,
<tests>
<test language="">
.....
</test>
</tests>
Теперь язык - это тип перечисления в классах, созданных из схемы. Он отлично работает, если язык указан, он не может десериализоваться, если он пуст (как показано в примере).
Изменить: Код для десериализации:
XmlSerializer xmlserializer = new XmlSerializer(type);
StringReader strreader = new StringReader(stringXML);
Object o = serializer.Deserialize(strreader);
Как я могу справиться с этим сценарием
Ответы
Ответ 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);
}
}
}
}