Нужно десериализовать объект. Проблема в том, что многие названия узлов — в верхнем регистре, соответсвено получается почти пустой экземпляр. Как заставить игнорировать регистр, возможно ли такое в C#?
Re: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, ivs13, Вы писали:
I>Нужно десериализовать объект. Проблема в том, что многие названия узлов — в верхнем регистре, соответсвено получается почти пустой экземпляр. Как заставить игнорировать регистр, возможно ли такое в C#?
Если отличия xml от объекта постоянны, то можно или применить атрибуты XmlAttribute\XmlElement к объекту или задать их в XmlAttributeOverrides.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, _FRED_, Вы писали:
_FR>Если отличия xml от объекта постоянны, то можно или применить атрибуты XmlAttribute\XmlElement к объекту или задать их в XmlAttributeOverrides.
Спасибо. Так и сделал, промучившись пол дня в поисках. Неужели для такой ерунды не предусмотрели галочку? Видать я изобретаю какой-то неправильный велосипед
Re[3]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, ivs13, Вы писали:
_FR>>Если отличия xml от объекта постоянны, то можно или применить атрибуты XmlAttribute\XmlElement к объекту или задать их в XmlAttributeOverrides.
I>Спасибо. Так и сделал, промучившись пол дня в поисках. Неужели для такой ерунды не предусмотрели галочку? Видать я изобретаю какой-то неправильный велосипед
Для какой ерунды-то? атрибуты позволяют относительногибко управлять связью между сериализуемым типом и xml. Обычно этого хватает "за глаза". А нечувствительный к регистру xml-это нечто противоестественное.
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, _FRED_, Вы писали:
_FR>А нечувствительный к регистру xml-это нечто противоестественное.
Это нечто противоестественное — Oracle Именно его механизмы формируют xml в верхнем регистре. Варианты, конечно, есть — перечислить все вручную. Но это же сколько возиться?!! Ну да это риторический вопрос. Может подскажете другое:
— можно ли тип boolean сохранять как 0/1 а не false/true?
— как задается форматы даты/времени, десятичный разделитель для дробных чисел?
Re[5]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, ivs13, Вы писали:
_FR>>А нечувствительный к регистру xml-это нечто противоестественное.
I>Это нечто противоестественное — Oracle Именно его механизмы формируют xml в верхнем регистре.
"Верхний регистр" и case insensitive — очень, мягко говоря, разные вещи. Да, форматирование странно, но, верю, что всегда одинаковое.
I>Варианты, конечно, есть — перечислить все вручную. Но это же сколько возиться?!! Ну да это риторический вопрос. Может подскажете другое: I> — можно ли тип boolean сохранять как 0/1 а не false/true? I> — как задается форматы даты/времени, десятичный разделитель для дробных чисел?
Ответы на все эти вопросы есть в спецификации xml. Отыскать их можно за недолго.
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, _FRED_, Вы писали:
_FR>Ответы на все эти вопросы есть в спецификации xml. Отыскать их можно за недолго.
Я верю. Если бы умел читать/искать/понимать документацию, то не обращался бы за помощью к другим.
Пока что проблему решил, дописав фиктивные поля в класс, и сериализую именно их, а не нужные, например:
[XmlIgnore] public Boolean Arhiv;
[XmlElement("ARHIV")]
public int SerializeArhivAsInt { get { return this.Arhiv ? 1 : 0; } set { this.Arhiv = Convert.ToBoolean(value); } }
может есть другой, правильный, вариант?
Re[7]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, ivs13, Вы писали:
_FR>>Ответы на все эти вопросы есть в спецификации xml. Отыскать их можно за недолго. I>Я верю. Если бы умел читать/искать/понимать документацию, то не обращался бы за помощью к другим.
3.2.2.1 Lexical representation
An instance of a datatype that is defined as ·boolean· can have the following legal literals {true, false, 1, 0}.
3.2.2.2 Canonical representation
The canonical representation for boolean is the set of literals {true, false}.
Простейший тест это подтверждает:
public class Test
{
public bool BooleanTrue { get; set; }
public bool BooleanFalse { get; set; }
public decimal Decimal { get; set; }
public double Double { get; set; }
public DateTime DateTime { get; set; }
}
public static void Parse() {
const string Xml =
@"<Test>
<BooleanTrue>1</BooleanTrue>
<BooleanFalse>0</BooleanFalse>
<Decimal>13.33</Decimal>
<Double>17.31</Double>
<DateTime>2011-02-22T20:28:26.4085098+03:00</DateTime>
</Test>";
var serializer = new XmlSerializer(typeof(Test));
using(var reader = new StringReader(Xml)) {
var result = serializer.Deserialize(reader);
}//using
}
То есть то "0" что "1" отлично воспринимаются парсером.
I>Пока что проблему решил, дописав фиктивные поля в класс, и сериализую именно их, а не нужные, например:
Так в чём же заключается ваша проблема? Вам нужно сохранять именно еденички-нолики? А почему? true/false не парсятся Ораклом? а с какой ошибкой? Уверены ли вы, что требуется именно boolean (в понимании xml) тип?
Там же по ссылке есть описания типов decimal и dateTime.
Help will always be given at Hogwarts to those who ask for it.
Re[8]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, _FRED_
_FR> true/false не парсятся Ораклом?
В Oracle SQL нет типа boolean. Приходится хранить как integer. Переданные true/false воспринимаются как строки и, конечно же, не могут превратиться в integer.
_FR> ОК, тогда рассказывайте, что конкретно вам нужно.
[Serializable(), XmlRoot("TEST")]
public class Test
{
[XmlElement("ARH")] public Boolean arh = true;
[XmlElement("DC")] public Double dc = 123.45;
[XmlElement("DT")] public DateTime dt = Convert.ToDateTime("23.11.2010 18:45:57");
public String SaveAsXml()
{
XmlSerializer ser = new XmlSerializer(typeof(Test));
StringWriter myWriter = new StringWriter();
ser.Serialize(myWriter, this);
return myWriter.ToString();
}
}
Здравствуйте, ivs13, Вы писали:
_FR>> true/false не парсятся Ораклом? I>В Oracle SQL нет типа boolean. Приходится хранить как integer. Переданные true/false воспринимаются как строки и, конечно же, не могут превратиться в integer.
В таком случае не совсем логично для сериализации использовать именно bool преобразование, верно? Используемый вами подход вполне оправдан, правда сеттер свойства SerializeArhivAsInt я бы переписал проще: "set { Arhiv = (value != 0); }"
_FR>> ОК, тогда рассказывайте, что конкретно вам нужно.
Теперь с датой. Жаль, если парсер Оракла не умеет парсить дату по стандарту xml, или он парсит не как дату?
В любом случае, если вам нужен какой-либо кастомный формат, самый просто способ — так же добавлять специальные свойства для сериализации.
Другой выход — реализовать IXmlSerializable, что позволит иметь объекты более "чистыми", но усложнит задачу.
Я бы поступил третьим образом. Отдельно имел бы модель объектов для сериализации-десериализации (если есть схема, такую можель можно генерировать автоматически с помощью xsd.exe) и отдельно — модель объектов, с которой работал бы из кода. Единственные накладные расходы в этом случае — написание логики преобразования из одних в другие. На практике это не доставляет трудностей.
I>И еще один вопрос: как реализовать Test.LoadFromXml(String xml); чтобы экземпляр десериализовал сам себя? Что-то вроде this = Deserialize().
Для чего?
Help will always be given at Hogwarts to those who ask for it.
Re[10]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, _FRED_, Вы писали:
_FR>Единственные накладные расходы в этом случае — написание логики преобразования из одних в другие. На практике это не доставляет трудностей.
Я как раз стремился от этого уйти. Накладные расходы — это копирование полей из одного экземпляра в другие? Неинтересно перечислять все поля.
I>>И еще один вопрос: как реализовать Test.LoadFromXml(String xml); чтобы экземпляр десериализовал сам себя? Что-то вроде this = Deserialize(). _FR>Для чего?
Obj obj = new Obj();
obj.ID = -1;
obj.Name = "test";
obj.SaveToDB(); // Здесь объект сериализует себя, записывается в БД (при этом БД его изменяет), после чего нужно перечитаться, чтобы получить измененные данные.
// Т.о. хотелось бы реализовать что-то подобное:
Obj.SaveToDB()
{
int ID = DBSave(this.GetAsXml());
String xml = DBGet(ID);
this.SetFromXml(xml); // Вот как сделать подобную вещь, не копируя явно все поля объекта?
}
Re[11]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, ivs13, Вы писали:
_FR>>Единственные накладные расходы в этом случае — написание логики преобразования из одних в другие. На практике это не доставляет трудностей. I>Я как раз стремился от этого уйти. Накладные расходы — это копирование полей из одного экземпляра в другие? Неинтересно перечислять все поля.
Не думаю что ошибусь если предположу, что по сравнению с сериализацией и сохранением в БД копирование не будет значимо. Но если "разбухший интерфейс" не стоит по вашему мнению этих расходов, то и не делайте.
I>>>И еще один вопрос: как реализовать Test.LoadFromXml(String xml); чтобы экземпляр десериализовал сам себя? Что-то вроде this = Deserialize(). _FR>>Для чего?
I> this.SetFromXml(xml); // Вот как сделать подобную вещь, не копируя явно все поля объекта?
С помощью XmlSerializer никак. Вообще говоря, в нынешнее время большой популярность пользуется идея разделения данных и логики (Фаулер vs "анемичная модель"). В вашем случае — сохраняемых данных и логики сохранения. Когда же всё понамешено вместе, обычно сложно да попросту и не интересно решать возникающие трудности.
Help will always be given at Hogwarts to those who ask for it.
Re[12]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, _FRED_, Вы писали:
_FR>Вообще говоря, в нынешнее время большой популярность пользуется идея разделения данных и логики (Фаулер vs "анемичная модель"). В вашем случае — сохраняемых данных и логики сохранения.
Т.е. логику сохранения разных объектов в БД вынести в отдельный класс?
Re[13]: Десериализация xml, НЕ чувствительная к регистру
Здравствуйте, ivs13, Вы писали:
_FR>>Вообще говоря, в нынешнее время большой популярность пользуется идея разделения данных и логики (Фаулер vs "анемичная модель"). В вашем случае — сохраняемых данных и логики сохранения. I>Т.е. логику сохранения разных объектов в БД вынести в отдельный класс?
Да. Тогда загрузка объекта — это и будет создание нового объекта.
Что бы восстановить существующий объект — можно сгенерить с помощью SGen.exe сборку .XmlSerializers и покопаться в ней, может быть удастся отыскать что-то, позволяющее зачитать xml в существующий объект.
Help will always be given at Hogwarts to those who ask for it.
Re[14]: Десериализация xml, НЕ чувствительная к регистру