Десериализация xml, НЕ чувствительная к регистру
От: ivs13  
Дата: 22.02.11 13:50
Оценка:
Нужно десериализовать объект. Проблема в том, что многие названия узлов — в верхнем регистре, соответсвено получается почти пустой экземпляр. Как заставить игнорировать регистр, возможно ли такое в C#?
Re: Десериализация xml, НЕ чувствительная к регистру
От: _FRED_ Черногория
Дата: 22.02.11 15:42
Оценка:
Здравствуйте, ivs13, Вы писали:

I>Нужно десериализовать объект. Проблема в том, что многие названия узлов — в верхнем регистре, соответсвено получается почти пустой экземпляр. Как заставить игнорировать регистр, возможно ли такое в C#?


Если отличия xml от объекта постоянны, то можно или применить атрибуты XmlAttribute\XmlElement к объекту или задать их в XmlAttributeOverrides.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Десериализация xml, НЕ чувствительная к регистру
От: ivs13  
Дата: 22.02.11 16:21
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Если отличия xml от объекта постоянны, то можно или применить атрибуты XmlAttribute\XmlElement к объекту или задать их в XmlAttributeOverrides.


Спасибо. Так и сделал, промучившись пол дня в поисках. Неужели для такой ерунды не предусмотрели галочку? Видать я изобретаю какой-то неправильный велосипед
Re[3]: Десериализация xml, НЕ чувствительная к регистру
От: _FRED_ Черногория
Дата: 22.02.11 16:32
Оценка: +1
Здравствуйте, 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, НЕ чувствительная к регистру
От: ivs13  
Дата: 22.02.11 16:43
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А нечувствительный к регистру xml-это нечто противоестественное.


Это нечто противоестественное — Oracle Именно его механизмы формируют xml в верхнем регистре. Варианты, конечно, есть — перечислить все вручную. Но это же сколько возиться?!! Ну да это риторический вопрос. Может подскажете другое:
— можно ли тип boolean сохранять как 0/1 а не false/true?
— как задается форматы даты/времени, десятичный разделитель для дробных чисел?
Re[5]: Десериализация xml, НЕ чувствительная к регистру
От: _FRED_ Черногория
Дата: 22.02.11 16:51
Оценка:
Здравствуйте, 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, НЕ чувствительная к регистру
От: ivs13  
Дата: 22.02.11 17:15
Оценка:
Здравствуйте, _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, НЕ чувствительная к регистру
От: _FRED_ Черногория
Дата: 22.02.11 17:37
Оценка:
Здравствуйте, ivs13, Вы писали:

_FR>>Ответы на все эти вопросы есть в спецификации xml. Отыскать их можно за недолго.

I>Я верю. Если бы умел читать/искать/понимать документацию, то не обращался бы за помощью к другим.

ОК, тогда рассказывайте, что конкретно вам нужно.

Смотрим в спеку xml: http://www.w3.org/TR/xmlschema-2/#boolean:

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, НЕ чувствительная к регистру
От: ivs13  
Дата: 23.02.11 09:44
Оценка:
Здравствуйте, _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();
      }
    }


выдает

<?xml version="1.0" encoding="utf-16"?>
<TEST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ARH>true</ARH>
  <DC>123.45</DC>
  <DT>2010-11-23T18:45:57</DT>
</TEST>

а нужно
  <ARH>1</ARH>
  <DT>23.11.2010 18:45:57</DT>


И еще один вопрос: как реализовать Test.LoadFromXml(String xml); чтобы экземпляр десериализовал сам себя? Что-то вроде this = Deserialize().
Re[9]: Десериализация xml, НЕ чувствительная к регистру
От: _FRED_ Черногория
Дата: 23.02.11 10:04
Оценка:
Здравствуйте, 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, НЕ чувствительная к регистру
От: ivs13  
Дата: 23.02.11 10:35
Оценка:
Здравствуйте, _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, НЕ чувствительная к регистру
От: _FRED_ Черногория
Дата: 23.02.11 10:47
Оценка:
Здравствуйте, 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, НЕ чувствительная к регистру
От: ivs13  
Дата: 23.02.11 10:55
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Вообще говоря, в нынешнее время большой популярность пользуется идея разделения данных и логики (Фаулер vs "анемичная модель"). В вашем случае — сохраняемых данных и логики сохранения.


Т.е. логику сохранения разных объектов в БД вынести в отдельный класс?
Re[13]: Десериализация xml, НЕ чувствительная к регистру
От: _FRED_ Черногория
Дата: 23.02.11 11:10
Оценка:
Здравствуйте, ivs13, Вы писали:

_FR>>Вообще говоря, в нынешнее время большой популярность пользуется идея разделения данных и логики (Фаулер vs "анемичная модель"). В вашем случае — сохраняемых данных и логики сохранения.

I>Т.е. логику сохранения разных объектов в БД вынести в отдельный класс?

Да. Тогда загрузка объекта — это и будет создание нового объекта.

Что бы восстановить существующий объект — можно сгенерить с помощью SGen.exe сборку .XmlSerializers и покопаться в ней, может быть удастся отыскать что-то, позволяющее зачитать xml в существующий объект.
Help will always be given at Hogwarts to those who ask for it.
Re[14]: Десериализация xml, НЕ чувствительная к регистру
От: ivs13  
Дата: 23.02.11 12:24
Оценка:
Здравствуйте, _FRED_, Вы писали:

Спасибо за помощь и разъяснения!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.