Comments.blogs

А как вы работаете с xml?

19 мар 2007 10:18
0
(Текст записи скрыт. Показать...)
Интересно, как сейчас в разных компаниях обстоит дело с работой с xml форматом? Используете или нет? Если да, то какие средства для чтения\записи? Какие именно фичи из xml используется?
Есть мнение, что мы изобретали в очередной раз свой велосипед – хотелось бы это обсудить и понять, так ли это .
Вкратце про эволюцию работы с xml у нас в Лесте читай в блоге...


Началась наша работа с xml с парсера TinyXml. Достаточно удобный и простой парсер. Его просто подключить, просто использовать. Его минусы проявляются только когда появляются огромные xml файлы или когда надо работать с частями этих файлов, хранить subNodes и т.п. – тут начинаются тормоза и проблемы с памятью. Также проблемой являлось то, что не было типизации – в любую ноду можно было записать все, что угодно и только в момент загрузки можно было сконвертировать в нужный тип из строки.
Вот кусок такого файла:

<IconName value="DE_PC1000"/>
<Icon value="TL/Icon/Ammo/DE_PC1000"/>
<ExploPower value="150"/>
<IsBomb value="true"/>

Дальнейшим шагом было написание товарищем Corvax (http://www.dtf.ru/person/info.php?id=1212) системы классов, имеющих у нас кодовое имя SMCC. Это фактически был набор классов, которые хранили в себе данные из xml и умели загружаться и сохраняться в него. Всё на умных указателях. Работать стало удобнее за счет того, что нам нужно было строго ограниченное число типов данных внутри xml (object, string, int, float, bool, wstring, data). Вот кусок такого файла:

<object name = "Second_Turret_155_Yamato">
<integer name = "Country" value = "2"/>
<string name = "Type" value = "Gun"/>
<boolean name = "Production" value = "false"/>
<float name = "Weight" value = "177"/>
</object>

Вот работа с ним:


for (CompoundObject::ConstIterator i = turrets->begin(),
iend = turrets->end();
i != iend;
++i
)
{
std::string name = i->first; // "Second_Turret_155_Yamato"
ObjectAttribute turret = i->second;

IntegerAttibute attrCountryId = turret->get("Country");
int attrCountryId = attrCountryId->getValue();

std::string turretType = turret->getAs<TypeId::String>("Gun")->getValue();

bool production = safeGetValue(turret, "Production", false);

Attribute attrWeight = turret->get("Weight");
double weight = As<TypeId::Float>(attrWeight)->getValue();
}


Этот файл уже имеет типизацию, которую можно проверять и выдавать Exception, если тип неправильный.
Минусом первого варианта системы SMCC было то, что она была надстройкой над TinyXml и вся загрузка и сохранение велась через нее.
Дальнейшей оптимизацией было создание своего парсера xml для нашего формата. Он легковесный и работает в несколько раз быстрее TinyXml.
Следующей мыслью было то, что у нас строго ограниченный набор типов в xml, а значит можно сделать и бинарный формат. Сделали. Получили прирост скорости парсинга xml еще в несколько раз. Например, файл сэйва занимал 50mb в xml, старый парсинг и сохранение могли занимать 10 и более секунд, а новый отрабатывает менее, чем за секунду.
Ну и недавно дошли руки до загрузки xml с помощью Loading inplace. Это вообще максимально быстрый алгоритм. Работает за счет того, что число типов ограничено.
Естественно, все форматы грузятся любым загрузчиком. Даже Loading inplace грузит обычный xml, правда медленно, т.к. сначала надо распарсить всю структуру.
Также пришлось написать утилиту, конвертирующую форматы xml в разные виды, чтобы можно было бинарные форматы конвертировать в текстовый для просмотра и редактирования, но т.к. большинство xml экспортятся из maya или базы данных, то делать это приходится нечасто.

В итоге сейчас мы имеем систему работы с xml, сочетающую в себе как плюсы бинарных файлов, так и удобство текстового xml формата.
А у вас есть такой велосипед?
Отправлено 19.03.2007 в 10:40
Отвечает на сообщение 186834
0
boost::property_tree плюс своя небольшая надстройка, чтобы конвертить безконтурный граф полиморфных объектов в текстовое дерево и обратно.
Отправлено 19.03.2007 в 10:49
Отвечает на сообщение 186835
0
Alexey Baskakov wrote:
>
> boost::property_tree плюс своя небольшая
> надстройка, чтобы конвертить безконтурный граф
> полиморфных объектов в текстовое дерево и
> обратно.


А пример такого xml файла и кода для работы с ним можно?
Отправлено 19.03.2007 в 12:28
Отвечает на сообщение 186837
0
Oleg Fedorov wrote:
> А пример такого xml файла и кода для работы с ним
> можно?


Самый простой пример (без сохранения иерархии и relationship) - конфиг:

struct Config
{
enum Domain_e
{
 DOMAIN_ART = 0
, DOMAIN_GAME_DESIGN = 1
, DOMAIN_PROGRAMMING = 2
, DOMAIN_SOUND = 3
};

std::string m_sUser;
std::string m_sPassword;
Domain_e m_eDomain;

bool m_bFileSystemFlat;
boost::filesystem::path m_sMediaPath;

int m_iAutosavePeriod; // minutes
boost::filesystem::path m_sAutosavePath;

struct Layout_c : public serialization::Layout_c < Config >
{
Layout_c()
{
Simple ( "user", &Config::m_sUser, "" );
Simple ( "password", &Config::m_sPassword, "" );
Enum ( "domain", &Config::m_eDomain, DOMAIN_GAME_DESIGN )
.Enumerator( DOMAIN_ART, "art" )
.Enumerator( DOMAIN_GAME_DESIGN, "game_design" )
.Enumerator( DOMAIN_PROGRAMMING, "programming" )
.Enumerator( DOMAIN_SOUND, "sound" )
;
Simple ( "filesystem_flat", &Config::m_bFileSystemFlat, true );
Simple ( "media_path", &Config::m_sMediaPath, "" );
Simple ( "autosave_period", &Config::m_iAutosavePeriod, 10 );
Simple ( "autosave_path", &Config::m_sAutosavePath, "" );
}
};
};

<?xml version="1.0" encoding="windows-1251"?>
<SkyStudio>
<Configuration>
<user>loyso</user>
<domain>programming</domain>
<filesystem_flat>true</filesystem_flat>
<media_path>C:/Dev/Repositories/media</media_path>
<autosave_period>2</autosave_period>
<autosave_path>C:/autosave</autosave_path>
</Configuration>
</SkyStudio>

Сериализация иерархии полиморфных объектов, в данном случае - коллекция
полиморфных объектов:

class Primitive
{
};

class PrimFloat : public Primitive
{
};

struct PrimitiveSerializer : public serialization::SerializeAbstract_T < Primitive >
{
PrimitiveSerializer()
{
RegisterType < PrimFloat > ( "float" );
RegisterType < PrimInt > ( "int" );
RegisterType < PrimBool > ( "bool" );
RegisterType < PrimVec2 > ( "vec2" );
RegisterType < PrimVec3 > ( "vec3" );
RegisterType < PrimVec4 > ( "vec4" );
RegisterType < PrimTexRect > ( "texrect" );
RegisterType < PrimColor > ( "color" );
RegisterType < PrimString > ( "string" );
RegisterType < PrimFileName > ( "filename" );
RegisterType < PrimLink > ( "link" );
RegisterType < PrimEnum > ( "enum" );
}
};

class AttributeStruct
{
...
struct Layout : public serialization::Layout_c < AttributeStruct >
{
Layout()
{
ContainerPtr( "primitives", &AttributeStruct::m_Primitives, serialization::Serializer < PrimitiveSerializer > () );
}
}
...
typedef std::list < Primitive * > Primitives_t;
Primitives_t m_Primitives;
}

в xml:

...
<primitives>
<_ type="float">
<name>yaw</name>
<min>-3.1415</min>
<max>3.1415</max>
</_>
<_ type="bool">
<name>open</name>
<default>true<default>
</_>
</primitives>

В общем, если честно то сейчас я бы не стал все это на C++ писать. И даже на C# бы не стал. Сейчас я бы DSL забабахал для описания и создания диаграмм классов и объектов. И компонентных диаграмм. Не только с целью реализации сериализации разумеется.
Oleg Fedorov  20.03.2007 12:34
Alexey Baskakov  20.03.2007 13:19
Oleg Fedorov  20.03.2007 15:35
В ветке ещё 4 сообщения
Отправлено 19.03.2007 в 13:12
Отвечает на сообщение 186835
0
> boost::property_tree плюс своя небольшая надстройка
Аналогично.
Отправлено 20.03.2007 в 14:46
Отвечает на сообщение 186834
0
Использовали http://www.tech-know-ware.com/lmx/
Очень хорошие впечатления. По схеме (xsd) автоматически генерится код маршалинга. Стоит денег, но не больших. Поддержка отвечала в течении 2х часов. Проблемы решались за день.
Отправлено 20.03.2007 в 15:32
Отвечает на сообщение 187116
0
Сергей Захаров wrote:
>
> Использовали http://www.tech-know-ware.com/lmx/
> Очень хорошие впечатления. По схеме (xsd)
> автоматически генерится код маршалинга. Стоит
> денег, но не больших. Поддержка отвечала в
> течении 2х часов. Проблемы решались за день.


4000USD - это небольшие деньги? Хорошо вам :)
Посмотрел их генерящийся код - страшный он, хотя не это, конечно, главное.
Мы никогда не использовали автогенерацию кода по xsd - неужели это действительно нужно и удобно? Обычно мы в нечасто вызываемых кусках кода просто берем значения из дерева атрибутов, а там, где нужна скорость, кешируем уже значения в структурах. Работает быстро, понятно и удобно.
Отправлено 21.03.2007 в 11:16
Отвечает на сообщение 187138
0
> 4000USD - это небольшие деньги? Хорошо вам :)

Нет, нам плохо :) мы не можем написать такой инструмент дешевле сами. Приходится платить.

> Мы никогда не использовали автогенерацию кода по xsd
> - неужели это действительно нужно и удобно?


Главный плюс xsd - стандартность. А это - инструменты и документация (куча книг и туториалов).

Кодогенерация по xsd позволяет делать очень оптимизированные парсеры под конкретную схему (теоретически, т.к. лично я не проверял перформанс lmx).

Из мелких приятностей - в xsd очень удобно прописывать constraints и default values. На простейшей валидации можно сэкономить.
Oleg Fedorov  21.03.2007 11:58
Отправлено 20.03.2007 в 22:32
Отвечает на сообщение 186834
0
Oleg Fedorov wrote:
>
> Комментарии к блогу персоны Oleg Fedorov
>
> Интересно, как сейчас в разных компаниях обстоит
> дело с работой с xml форматом? Используете или
> нет? Если да, то какие средства для
> чтения\записи? Какие именно фичи из xml
> используется?
> Есть мнение, что мы изобретали в очередной раз
> свой велосипед – хотелось бы это обсудить и
> понять, так ли это .
> Вкратце про эволюцию работы с xml у нас в Лесте
> читай в блоге...
>
>
>
> Больше в блоге...
>
> http://www.dtf.ru/blog/read.php?id=45064



Почти такой же велосипед. Проходит под аббревиатурой UD.
Comments.blogs
Списки доступа
  • Подписчики [789]
Права доступа
У обсуждений в этой группе различные ограничения доступа.
Пользователи имеют персональные права доступа к обсуждениям.

Copyright © 2021 ООО "ДТФ.РУ". Все права защищены.

Воспроизведение материалов или их частей в любом виде и форме без письменного согласия запрещено.

Замечания и предложения отправляйте через форму обратной связи.

Пользовательское соглашение