В платформе 1С:Предприятие 7.7 отсутствует нативная поддержка формата JSON, в отличие от старших версий платформы 1С 8. При этом интеграции с современными веб-сервисами, маркетплейсами и внешними базами данных требуют регулярного приема и разбора данных в этом стандарте. Рассмотрим доступные и эффективные способы парсинга JSON в среде 1С 7.7, разберем готовый программный код на базе системных скриптов, а также проанализируем узкие места и альтернативные варианты реализации.
Прежде чем приступать к разбору данных, выясним причину технических сложностей интеграции формата JSON в устаревшей платформе:
Текст кириллические символы превращаются в нечитаемые символы («кракозябры»). Кроме того, строки могут содержать экранированные Unicode-последовательности вида \uXXXX.СписокЗначений позволяет хранить вложенные структуры, однако он не предназначен для быстрой выборки и поиска по составным ключам. Стандартная ТаблицаЗначений также осуществляет поиск методом полного перебора, что создает задержки при обработке массивов с тысячами записей.Наиболее популярным методом без использования специализированных внешних компонент является обращение к Windows Script Host через COM-объект MSScriptControl.ScriptControl. Скриптовый движок принимает строку JSON, выполняет ее парсинг средствами JScript и возвращает управление в 1С.
Разберем по шагам реализацию данного механизма. Сначала подготовим инициализирующий код, который внедряет вспомогательные функции JScript для безопасного обхода структуры данных:
Перем JSON_ctrl;
Процедура JSON_Init()
Если ПустоеЗначение(JSON_ctrl) = 0 Тогда
Возврат;
КонецЕсли;
JSON_ctrl = СоздатьОбъект("MSScriptControl.ScriptControl");
JSON_ctrl.Language = "jscript";
код = "
| function parseJSON(strJSON) {
| var tmpFunc = (new Function('return(' + strJSON + ');'))();
| return(tmpFunc);
| }
|
| function aGet(Array, index) {
| return(Array[index]);
| }
|
| function oKey(Obj, index) {
| var size = 0, key;
| for (key in Obj) {
| if (size == index) break;
| if (Obj.hasOwnProperty(key)) size++;
| }
| return(key);
| }
|
| function oValueByKey(Obj, key) {
| return(Obj[key]);
| }
|
| function oSize(Obj) {
| var size = 0, key;
| for (key in Obj) {
| if (Obj.hasOwnProperty(key)) size++;
| }
| return(size);
| }
|
| function eType(Element) {
| if (Element instanceof Array) {
| return('array');
| } else if (Object.prototype.toString.call(Element) === '[object Array]') {
| return('array');
| } else {
| return(typeof(Element));
| }
| }
|";
JSON_ctrl.AddCode(код);
КонецПроцедуры
Теперь рассмотрим рекурсивную функцию jsonВСписок, которая преобразует разобранный JScript-объект в иерархию стандартных объектов СписокЗначений платформы 1С 7.7:
Функция jsonВСписок(obj)
сп = СоздатьОбъект("СписокЗначений");
ТипОбъекта = JSON_ctrl.run("eType", obj);
Если ТипОбъекта = "object" Тогда
КоличествоЭлементов = JSON_ctrl.run("oSize", obj);
Для н = 0 По КоличествоЭлементов - 1 Цикл
Ключ = JSON_ctrl.run("oKey", obj, н);
Значение = JSON_ctrl.run("oValueByKey", obj, Ключ);
ТипЗнач = JSON_ctrl.run("eType", Значение);
Если Найти("number, string, boolean", ТипЗнач) > 0 Тогда
сп.ДобавитьЗначение(Значение, Ключ);
ИначеЕсли Найти("object, array", ТипЗнач) > 0 Тогда
сп.ДобавитьЗначение(jsonВСписок(Значение), Ключ);
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипОбъекта = "array" Тогда
Для н = 0 По obj.length - 1 Цикл
Значение = JSON_ctrl.run("aGet", obj, н);
ТипЗнач = JSON_ctrl.run("eType", Значение);
Если Найти("number, string, boolean", ТипЗнач) > 0 Тогда
сп.ДобавитьЗначение(Значение, СокрЛП(Строка(н)));
ИначеЕсли Найти("object, array", ТипЗнач) > 0 Тогда
сп.ДобавитьЗначение(jsonВСписок(Значение), СокрЛП(Строка(н)));
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат сп;
КонецФункции
Функция сз_FromJSON(стр) Экспорт
JSON_Init();
obj = JSON_ctrl.run("parseJSON", стр);
сз = jsonВСписок(obj);
Возврат сз;
КонецФункции
Обратим внимание на нюансы эксплуатации данного подхода в промышленной среде:
MSScriptControl.ScriptControl — это 32-битный компонент. В современных версиях Windows он может отсутствовать в реестре. Для корректной работы требуется выполнить ручную регистрацию библиотеки msscript.ocx через команду regsvr32 %windir%\SysWOW64\msscript.ocx.new Function('return(' + strJSON + ');') чувствительна к неэкранированным символам перевода каретки и табуляции в значениях полей. Перед отправкой строки в parseJSON необходимо экранировать служебные символы.Если производительности или возможностей скрипт-контрола недостаточно, проанализируем другие надежные инструменты:
MSScriptControl можно подключить COM-объект htmlfile. Данный компонент эмулирует браузерное окружение и поддерживает вызов нативного метода JSON.parse(), что обеспечивает более высокую скорость и безопасность при разборе текста по сравнению с eval.Текст. Используем объект ADODB.Stream, задав свойство кодировки utf-8. Это позволит считать файл без искажения кириллицы и передать готовую ANSI-строку на вход парсеру.ИндексированнаяТаблица из надстройки 1С++. Это обеспечит построение составных индексов и мгновенный поиск элементов по ключам без последовательного сканирования строк.1cv7s.exe.