1с сериализация дерева значений

Универсальный метод сериализации значений в XML для локальных баз 1С на любом типе клиента под платформы 8.2 и 8.3

Однако, при знакомстве с мобильной платформой выяснились следующие проблемы: старые добрые функции для серилизации не работают — это ЗначениеИзВнутСтроки() и ЗначениеВоВнутСтроку(). Точнее их вообще нет здесь.

Так как при создании моей Консоли Запросов я использовал не только платформу 8.3, но и 8.2 — то единственным доступным вариантом в моем случае остался 2-й метод.

Универсальная Сериализация через XML

Стандартно для этих целей существуют следующие функции из БСП:

// Строка - XML-строка. // Функция ЗначениеВСтрокуXML(Значение) Экспорт ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Значение); Возврат ЗаписьXML.Закрыть(); КонецФункции // Выполняет преобразование (десериализацию) XML-строки в значение. // См. также ЗначениеВСтрокуXML. // // Параметры: // СтрокаXML - Строка - XML-строка, с сериализованным объектом.. // // Возвращаемое значение: // Произвольный - значение, полученное из переданной XML-строки. // Функция ЗначениеИзСтрокиXML(СтрокаXML) Экспорт ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку(СтрокаXML); Значение=СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Возврат Значение; КонецФункции

Эти функции, взятые из БСП, — хорошие. Однако передать через них серьезные объекты (в моем случае это был тип данных РезультатЗапроса) без выгрузки или других танцев с бубном в рамках портирования консоли на мобильные платформы оказалось абсолютно невозможным, так как данные типы тип не сериализуются XDTO.

Однако для этого можно применить следующее правило, которое может работать в пределах одной базы:

  1. Если тип сериализуется — ничего не делаем. Сразу преобразуем.
  2. Если нельзя сериализовать- упаковываем в хранилище значений. Следует отметить, что хранилище значений упаковывается также, чтобы с ним не было проблем.

Итоговые правки в код дают следующие функции:

// Преобразованы в могут быть любые объекты (дополнено через ХранилищеЗначения. // См. также ЗначениеИзСтрокиXML. // // Параметры: // Значение - Произвольный - значение, которое необходимо сериализовать в XML-строку. // // Возвращаемое значение: // Строка - XML-строка. // Функция ЗначениеВСтрокуXML(Значение) Экспорт ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); Если Значение=Тип("ХранилищеЗначения") Тогда //Сохраняем жизнь исходному типу - через оборачивание. ХранилищеЗначения=новый ХранилищеЗначения(Значение); СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ХранилищеЗначения); иначе //Выполняем Сериализацию: попытка СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Значение); исключение ХранилищеЗначения=новый ХранилищеЗначения(Значение); СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ХранилищеЗначения); КонецПопытки; КонецЕсли; Возврат ЗаписьXML.Закрыть(); КонецФункции // Выполняет преобразование (десериализацию) XML-строки в значение. // См. также ЗначениеВСтрокуXML. // // Параметры: // СтрокаXML - Строка - XML-строка, с сериализованным объектом.. // // Возвращаемое значение: // Произвольный - значение, полученное из переданной XML-строки. // Функция ЗначениеИзСтрокиXML(СтрокаXML) Экспорт ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку(СтрокаXML); ХранилищеЗначение=СериализаторXDTO.ПрочитатьXML(ЧтениеXML); //Восстанавливаем значение из Хранилища: Если ХранилищеЗначение=Тип("ХранилищеЗначения") Тогда Возврат ХранилищеЗначение.Получить(); иначе Возврат ХранилищеЗначение; КонецЕсли; КонецФункции

Если есть необходимость ввести универсальную функцию, которая совместима на компьютерных платформах со старым внутренним форматом 1С (мне понадобилось для работы с Консолью Запросов на Windows), тогда полученные универсальные функции:

Функция УниверсальнаяЗначениеВСтрокуВнутр(Значение) Попытка возврат Вычислить("ЗначениеВСтрокуВнутр(Значение)"); Исключение //Для мобильных приложений выполняем по правилам XMl-Функций, которые были переделаны: возврат ЗначениеВСтрокуXML(Значение); КонецПопытки; КонецФункции Функция УниверсальнаяЗначениеИзСтрокиВнутр(Значение) Попытка возврат Вычислить("ЗначениеИзСтрокиВнутр(Значение)"); Исключение //Для мобильных приложений выполняем по правилам XMl-Функций, которые были переделаны: возврат ЗначениеИзСтрокиXML(Значение); КонецПопытки; КонецФункции 

PS: приведенными функциями в пределах одной базы можно пользоваться на следующих платформах:

  1. Компьютерные: 1С 8.2 и 1С 8.3 — Тонкий, Толстый, ВебКлиент.
  2. На мобильных платформах 8.3 можно использовать универсальные переделанные функции БСП для аналога внутренних значений.
Читайте также:  План посадки деревьев кустарников

Тестировалось на платформах 8.2 и 8.3. Режим совместимости с 8.1 не пострадал.

Источник

Как преобразовать выборку (дерево) в XML?

Вопрос для меня, новый. Пока ответа не нашел. Ручками описывать XML файл не хочу.

Есть иерархическая выборка. Как из нее быстро получить XML?

ЗаписьXML=Новый ЗаписьXML();
ЗаписьXML.ОткрытьФайл(«c:\doc.xml»);
ЗаписьXML.ЗаписатьНачалоЭлемента(«Root»);

Значения данного типа не могут быть представлены в XML

в справке выборку вообще нельзя записать этим методом

задачу можно сформулировать по другому:
надо сериализовать выборку

(13) попробую. Но в ЗаписатьXML нет поддержки этого типа.

Как еще можно сериализовать?

Зато есть в СериализаторXDTO
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам));

а теперь обратная задача — есть XML файл, как быстро получить его структуру в виде дерева или подобного.

(0) Вот не оптимальный метод. Доработай напильником

Процедура ЗаписатьСтроку(СтрокаДерева, ЗаписьXML, КолонкиДерева)
Для каждого Строка из СтрокиДерева.Строки Цикл
ЗаписьXML.ЗаписатьНачалоЭлемента(«СтрокаДерева»);
Для каждого Колонка из КолонкиДерева Цикл
ЗаписьXML.ЗаписатьАтрибут(Колонка.Имя, Строка[Колонка.Имя]);
КонецЦикла;
Если Строка.Строки.Количество() > 0 Тогда
ЗаписатьСтроку(Строка, ЗаписьXML, КолонкиДерева);
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецПроцедуры

Для каждого Строка из Дерево.Строки Цикл
ЗаписатьСтроку(Строка, ЗаписьXML, Дерево.Колонки);

Кажись через COMОбъект(Msxml2.DOMDocument.3.0) можно обратиться к любому элементу. Для моей задачи подхиодит, хоть и избыточно

Источник

Сериализация прикладных типов 1С:Предприятия в JSON

Некоторое время назад мы рассказывали о том, что в платформе реализованы средства работы с JSON. Потоковая запись/чтение и сериализация примитивных типов и коллекций.

Теперь мы рады рассказать вам о том, что мы полностью автоматизировали работу с JSON и реализовали в платформе третью группу средств. Они позволяют сериализовать в JSON прикладные типы 1С:Предприятия: ссылки, объекты, наборы записей и вообще любые типы, для которых поддерживается XDTO сериализация. Конечно же, мы обеспечили и обратную операцию — десериализацию.

Зачем это нужно

Прежде всего, и в основном, XDTO сериализацию в JSON мы рекомендуем использовать при обмене данными между двумя прикладными решениями 1С:Предприятия. По сравнению с XML формат JSON более компактный, сериализация/десериализация в/из JSON выполняется быстрее. Кроме этого мы предприняли дополнительные меры для того, чтобы сократить объём передаваемых данных.

Читайте также:  Покрытие дерева клеем пва

Кроме обмена между приложениями 1С:Предприятия этот механизм можно использовать и для обмена с внешними системами, готовыми принимать типы данных 1С:Предприятия. Например, XDTO сериализацию в JSON можно использовать для организации собственного HTTP интерфейса прикладного решения. Сервис на платформе 1С:Предприятия будет формировать ответ в памяти в виде строки JSON. А затем передавать её при помощи объекта HTTPСервисОтвет. Реализованный нами механизм сериализации полностью соответствует стандарту JSON. Поэтому внешняя система не должна испытывать каких-либо трудностей с десериализацией.

Использование XDTO сериализации в JSON для других задач видится нам маловероятным. Потому что если внешняя система не готова работать с прикладными типами 1С:Предприятия, то зачем их ей передавать? А если предполагается обмениваться только примитивными типами и коллекциями, то для этой задачи хорошо подходят методы ПрочитатьJSON() и ЗаписатьJSON(), о которых мы рассказывали ранее.

Как это выглядит

Простейший код, выполняющий сериализацию элемента справочника, может выглядеть так:

В результате будет получен файл JSON следующего содержания:

Десериализацию такого файла можно выполнить следующим кодом:

В результате будет получен элемент справочника Контрагенты с наименованием Мосхлеб ОАО и кодом 000000012.

Особенности сериализации

Как вы уже могли заметить, сериализация/десериализация выполняется с помощью объекта СериализаторXDTO. Поэтому получаемая структура документа имеет «родовые черты» XML, JSON получается «похожим» на XML. Это оказывает отрицательное влияние и на «читаемость» и на компактность файла. Это своеобразная «плата» за удобства, получаемые от использования XDTO. Если же «чистота» получаемого JSON имеет для вас решающее значение, мы рекомендуем использовать инструменты, о которых мы рассказывали ранее.

Общие принципы сериализации в JSON идентичны XDTO сериализации в XML. В частности:

  • Структура данных соответствует структуре XML документа;
  • Имеются незначительные отличия, связанные с особенностями хранения типов и представлением массивов в JSON;
  • Порядок и состав свойств JSON соответствует структуре объекта конфигурации и не может изменяться.
Читайте также:  Какие деревья можно посадить в зиму

Кроме этого есть одна важная особенность. В отличие от XML, для записи начала объекта JSON нет необходимости указывать его имя. По этой причине сериализация/десериализация JSON может выполняться одним из двух способов.

Либо при сериализации вы указываете явное назначение типа и потом десериализуете без указания типа считываемого значения:

Либо вы сериализуете в JSON без явного назначения типа. Но тогда тип нужно будет указать при десериализации:

Ещё одна особенность сериализации заключается в том, что мы стремились оптимизировать объём результирующего файла. Поэтому для встроенных типов платформы пространства имен не записываются полностью в отдельном свойстве JSON, а указываются в виде префикса перед типом:

В данном случае префикс jcfg обозначает пространство имён http://v8.1c.ru/8.1/data/enterprise/current-config. Соответствие префиксов пространствам имён «зашито» в платформу. Поэтому каких-либо трудностей с определениями типов при обмене между приложениями 1С:Предприятия не возникает.

А при обмене с внешними системами, для правильной десериализации типов платформы, внешней системе понадобится полная таблица соответствия. Такая таблица есть, и она опубликована в документации.

Особенности десериализации

Общие принципы десериализации также связаны с использованием механизма XDTO. В частности:

  • Десериализуются только те типы, которые поддерживают XDTO сериализацию;
  • Порядок свойств JSON должен соответствовать структуре объекта конфигурации.

При десериализации у вас есть возможность изменить получаемые данные. Для этого, как и в случае с примитивными типами и коллекциями, вы можете использовать функцию восстановления.

Эта возможность может потребоваться, например, для того, чтобы при переносе данных из одного прикладного решения в другое, заменить в них ссылки на связанные объекты. Так, чтобы после переноса эти данные ссылались уже на объекты новой базы. Или, например, для того, чтобы удалить из данных информацию, имеющую смысл только в исходной базе.

Допустим, в исходной базе описание товара хранится в HTML виде. А в вашей базе достаточно текстового описания, или такое описание вообще не нужно. Потому что у вас будет собственное описание.

Тогда, имея файл следующего содержания:

 < "#type": "jcfg:CatalogObject.Товары", "#value": < "IsFolder": false, "Ref": "2d97a749-8ea9-11dc-8ca1-000d8843cd1b", "DeletionMark": false, "Parent": "87f1c226-9679-11db-a9b2-00055d49b45e", "Code": "000000030", "Description": "Колбаса", "Артикул": "Kol67", "Поставщик": "95f19911-d7c6-11db-a9bd-00055d49b45e", "ФайлКартинки": "00000000-0000-0000-0000-000000000000", "Вид": "Товар", "Штрихкод": "", "Описание":"     \n 

Колбаса \"Докторская\" вареная высшего сорта из охлажденного мяса

\n

Вес - 500 г.

\n " > >

вы можете при десериализации использовать собственную функцию восстановления, в которой очистить свойство Описание:

В результате этого кода будет прочитан объект СправочникОбъект.Товары, у которого реквизит Описание будет содержать пустую строку:

Источник

Оцените статью