|
12 | 12 | Функция Сериализовать(Знач Значение, УровеньОтступа = 0) Экспорт
|
13 | 13 |
|
14 | 14 | ТипЗначения = ТипЗнч(Значение);
|
| 15 | + Результат = ""; |
| 16 | + |
| 17 | + // Если это корневой уровень, добавляем разделитель документа |
| 18 | + Если УровеньОтступа = 0 Тогда |
| 19 | + Результат = "---" + Символы.ПС; |
| 20 | + КонецЕсли; |
15 | 21 |
|
16 | 22 | Если ТипЗначения = Тип("Строка") Тогда
|
17 |
| - Возврат СериализоватьСтроку(Значение); |
| 23 | + Результат = Результат + СериализоватьСтроку(Значение); |
18 | 24 | ИначеЕсли ТипЗначения = Тип("Число") Тогда
|
19 |
| - Возврат СериализоватьЧисло(Значение); |
| 25 | + Результат = Результат + СериализоватьЧисло(Значение); |
20 | 26 | ИначеЕсли ТипЗначения = Тип("Булево") Тогда
|
21 |
| - Возврат СериализоватьБулево(Значение); |
| 27 | + Результат = Результат + СериализоватьБулево(Значение); |
22 | 28 | ИначеЕсли ТипЗначения = Тип("Массив") Тогда
|
23 |
| - Возврат СериализоватьМассив(Значение, УровеньОтступа); |
| 29 | + Результат = Результат + СериализоватьМассив(Значение, УровеньОтступа); |
24 | 30 | ИначеЕсли ТипЗначения = Тип("Структура") Или ТипЗначения = Тип("Соответствие") Тогда
|
25 |
| - Возврат СериализоватьОбъект(Значение, УровеньОтступа); |
| 31 | + Результат = Результат + СериализоватьОбъект(Значение, УровеньОтступа); |
26 | 32 | ИначеЕсли Значение = Неопределено Тогда
|
27 |
| - Возврат "null"; |
| 33 | + Результат = Результат + "null"; |
28 | 34 | ИначеЕсли ТипЗначения = Тип("Дата") Тогда
|
29 | 35 | // Используем JSON писателя для корректной сериализации дат
|
30 | 36 | ЗаписьJSON = Новый ЗаписьJSON;
|
31 | 37 | ЗаписьJSON.УстановитьСтроку();
|
32 | 38 | ЗаписатьJSON(ЗаписьJSON, Значение);
|
33 |
| - Возврат ЗаписьJSON.Закрыть(); |
| 39 | + Результат = Результат + ЗаписьJSON.Закрыть(); |
34 | 40 | Иначе
|
35 | 41 | // Для неизвестных типов пытаемся использовать JSON сериализацию
|
36 | 42 | Попытка
|
37 | 43 | ЗаписьJSON = Новый ЗаписьJSON;
|
38 | 44 | ЗаписьJSON.УстановитьСтроку();
|
39 | 45 | ЗаписатьJSON(ЗаписьJSON, Значение);
|
40 |
| - Возврат ЗаписьJSON.Закрыть(); |
| 46 | + Результат = Результат + ЗаписьJSON.Закрыть(); |
41 | 47 | Исключение
|
42 | 48 | // Если JSON не справился, используем строковое представление
|
43 |
| - Возврат СериализоватьСтроку(Строка(Значение)); |
| 49 | + Результат = Результат + СериализоватьСтроку(Строка(Значение)); |
44 | 50 | КонецПопытки;
|
45 | 51 | КонецЕсли;
|
46 | 52 |
|
| 53 | + // Если это корневой уровень, добавляем разделитель конца документа |
| 54 | + Если УровеньОтступа = 0 Тогда |
| 55 | + Результат = Результат + Символы.ПС + "..."; |
| 56 | + КонецЕсли; |
| 57 | + |
| 58 | + Возврат Результат; |
| 59 | + |
47 | 60 | КонецФункции
|
48 | 61 |
|
49 | 62 | // Сериализация строки
|
|
61 | 74 | Возврат """""";
|
62 | 75 | КонецЕсли;
|
63 | 76 |
|
| 77 | + // Если строка содержит переносы строк, используем блочный стиль |
| 78 | + Если СтрНайти(Значение, Символы.ПС) > 0 ИЛИ СтрНайти(Значение, Символы.ВК) > 0 Тогда |
| 79 | + Возврат СериализоватьМногострочнуюСтроку(Значение); |
| 80 | + КонецЕсли; |
| 81 | + |
64 | 82 | // Проверяем, нужно ли заключать в кавычки
|
65 | 83 | Если ТребуетсяЗаключениеВКавычки(Значение) Тогда
|
66 | 84 | // Используем JSON писателя для корректного экранирования строки
|
|
74 | 92 |
|
75 | 93 | КонецФункции
|
76 | 94 |
|
| 95 | +// Сериализация многострочной строки |
| 96 | +// |
| 97 | +// Параметры: |
| 98 | +// Значение - Строка - многострочная строка для сериализации |
| 99 | +// |
| 100 | +// Возвращаемое значение: |
| 101 | +// Строка - YAML представление многострочной строки |
| 102 | +// |
| 103 | +Функция СериализоватьМногострочнуюСтроку(Значение) |
| 104 | + |
| 105 | + // Нормализуем переносы строк |
| 106 | + НормализованноеЗначение = СтрЗаменить(Значение, Символы.ВК, Символы.ПС); |
| 107 | + |
| 108 | + // Разделяем на строки |
| 109 | + Строки = СтрРазделить(НормализованноеЗначение, Символы.ПС, Ложь); |
| 110 | + |
| 111 | + // Используем блочный литеральный стиль | |
| 112 | + Результат = "|" + Символы.ПС; |
| 113 | + |
| 114 | + Для Каждого Строка Из Строки Цикл |
| 115 | + Результат = Результат + " " + Строка + Символы.ПС; |
| 116 | + КонецЦикла; |
| 117 | + |
| 118 | + // Убираем последний перенос строки |
| 119 | + Результат = Лев(Результат, СтрДлина(Результат) - 1); |
| 120 | + |
| 121 | + Возврат Результат; |
| 122 | + |
| 123 | +КонецФункции |
| 124 | + |
77 | 125 | // Сериализация числа
|
78 | 126 | //
|
79 | 127 | // Параметры:
|
|
123 | 171 |
|
124 | 172 | Результат = "";
|
125 | 173 | Отступ = ПолучитьОтступ(УровеньОтступа);
|
| 174 | + ПервыйЭлемент = Истина; |
126 | 175 |
|
127 | 176 | Для Каждого Элемент Из Массив Цикл
|
128 |
| - Результат = Результат + Символы.ПС; |
| 177 | + Если НЕ ПервыйЭлемент Тогда |
| 178 | + Результат = Результат + Символы.ПС; |
| 179 | + КонецЕсли; |
| 180 | + ПервыйЭлемент = Ложь; |
| 181 | + |
| 182 | + ТипЭлемента = ТипЗнч(Элемент); |
129 | 183 |
|
130 |
| - СериализованныйЭлемент = Сериализовать(Элемент, УровеньОтступа + 1); |
131 |
| - МассивСтрок = СтрРазделить(СериализованныйЭлемент, Символы.ПС, Ложь); |
132 |
| - СериализованныйЭлемент = ""; |
133 |
| - ОтступВложения = ПолучитьОтступ(УровеньОтступа + 1); |
134 |
| - Для каждого Строка Из МассивСтрок Цикл |
135 |
| - СериализованныйЭлемент = СериализованныйЭлемент + ?(ЗначениеЗаполнено(СериализованныйЭлемент), Символы.ПС + ОтступВложения, Отступ + "- ") + СокрЛП(Строка); |
136 |
| - КонецЦикла; |
137 |
| - // Убираем последний отступ |
138 |
| - СериализованныйЭлемент = СокрП(СериализованныйЭлемент); |
139 |
| - Результат = Результат + СериализованныйЭлемент; |
| 184 | + // Для объектов и массивов используем специальную обработку |
| 185 | + Если ТипЭлемента = Тип("Структура") ИЛИ ТипЭлемента = Тип("Соответствие") ИЛИ ТипЭлемента = Тип("Массив") Тогда |
| 186 | + СериализованныйЭлемент = Сериализовать(Элемент, УровеньОтступа + 1); |
| 187 | + Результат = Результат + ОбработатьМногострочныйЭлементМассива(СериализованныйЭлемент, Отступ, УровеньОтступа); |
| 188 | + Иначе |
| 189 | + // Простые значения (строки, числа, булево) |
| 190 | + СериализованныйЭлемент = Сериализовать(Элемент, УровеньОтступа + 1); |
| 191 | + Результат = Результат + Отступ + "- " + СериализованныйЭлемент; |
| 192 | + КонецЕсли; |
140 | 193 |
|
141 | 194 | КонецЦикла;
|
142 | 195 |
|
143 | 196 | Возврат Результат;
|
144 | 197 |
|
145 | 198 | КонецФункции
|
146 | 199 |
|
| 200 | +// Обработка многострочного элемента в массиве |
| 201 | +// |
| 202 | +// Параметры: |
| 203 | +// СериализованныйЭлемент - Строка - сериализованный элемент с переносами строк |
| 204 | +// Отступ - Строка - базовый отступ для массива |
| 205 | +// УровеньОтступа - Число - уровень отступа |
| 206 | +// |
| 207 | +// Возвращаемое значение: |
| 208 | +// Строка - отформатированный элемент массива |
| 209 | +// |
| 210 | +Функция ОбработатьМногострочныйЭлементМассива(СериализованныйЭлемент, Отступ, УровеньОтступа) |
| 211 | + |
| 212 | + МассивСтрок = СтрРазделить(СериализованныйЭлемент, Символы.ПС, Ложь); |
| 213 | + ОжидаемыйОтступ = ПолучитьОтступ(УровеньОтступа + 1); |
| 214 | + |
| 215 | + Результат = ""; |
| 216 | + Для Инд = 0 По МассивСтрок.Количество() - 1 Цикл |
| 217 | + СтрокаЭлемента = МассивСтрок[Инд]; |
| 218 | + |
| 219 | + Если Инд = 0 Тогда |
| 220 | + // Первая строка - убираем ожидаемый отступ и добавляем "- " |
| 221 | + СтрокаБезОтступа = УбратьОжидаемыйОтступ(СтрокаЭлемента, ОжидаемыйОтступ); |
| 222 | + Результат = Результат + Отступ + "- " + СтрокаБезОтступа; |
| 223 | + Иначе |
| 224 | + // Остальные строки - заменяем ожидаемый отступ на отступ массива + 2 пробела |
| 225 | + ОстатокСтроки = УбратьОжидаемыйОтступ(СтрокаЭлемента, ОжидаемыйОтступ); |
| 226 | + Результат = Результат + Символы.ПС + Отступ + " " + ОстатокСтроки; |
| 227 | + КонецЕсли; |
| 228 | + КонецЦикла; |
| 229 | + |
| 230 | + Возврат Результат; |
| 231 | + |
| 232 | +КонецФункции |
| 233 | + |
| 234 | +// Убрать ожидаемый отступ из строки |
| 235 | +// |
| 236 | +// Параметры: |
| 237 | +// СтрокаЭлемента - Строка - исходная строка |
| 238 | +// ОжидаемыйОтступ - Строка - ожидаемый отступ для удаления |
| 239 | +// |
| 240 | +// Возвращаемое значение: |
| 241 | +// Строка - строка без ожидаемого отступа |
| 242 | +// |
| 243 | +Функция УбратьОжидаемыйОтступ(СтрокаЭлемента, ОжидаемыйОтступ) |
| 244 | + |
| 245 | + Если СтрНачинаетсяС(СтрокаЭлемента, ОжидаемыйОтступ) Тогда |
| 246 | + Возврат Сред(СтрокаЭлемента, СтрДлина(ОжидаемыйОтступ) + 1); |
| 247 | + Иначе |
| 248 | + Возврат СокрЛП(СтрокаЭлемента); |
| 249 | + КонецЕсли; |
| 250 | + |
| 251 | +КонецФункции |
| 252 | + |
147 | 253 | // Сериализация объекта
|
148 | 254 | //
|
149 | 255 | // Параметры:
|
|
161 | 267 |
|
162 | 268 | Результат = "";
|
163 | 269 | Отступ = ПолучитьОтступ(УровеньОтступа);
|
| 270 | + ПервыйЭлемент = Истина; |
164 | 271 |
|
165 | 272 | Для Каждого КлючЗначение Из Объект Цикл
|
166 |
| - Результат = Результат + Символы.ПС; |
| 273 | + Если НЕ ПервыйЭлемент Тогда |
| 274 | + Результат = Результат + Символы.ПС; |
| 275 | + КонецЕсли; |
| 276 | + ПервыйЭлемент = Ложь; |
167 | 277 |
|
168 | 278 | Ключ = КлючЗначение.Ключ;
|
169 | 279 | Значение = КлючЗначение.Значение;
|
170 | 280 |
|
171 | 281 | СериализованныйКлюч = СериализоватьКлюч(Ключ);
|
172 | 282 | СериализованноеЗначение = Сериализовать(Значение, УровеньОтступа + 1);
|
173 | 283 |
|
174 |
| - |
| 284 | + // Если значение содержит переносы строк (массив или сложный объект), |
| 285 | + // то нужно размещать его на новой строке с правильными отступами |
| 286 | + Если СтрНайти(СериализованноеЗначение, Символы.ПС) > 0 Тогда |
| 287 | + // Сложное значение - размещаем на новой строке |
| 288 | + // Но для многострочных строк с | добавляем пробел |
| 289 | + Если СтрНачинаетсяС(СериализованноеЗначение, "|") Тогда |
| 290 | + Результат = Результат + Отступ + СериализованныйКлюч + ": " + СериализованноеЗначение; |
| 291 | + Иначе |
| 292 | + // Для массивов и объектов - значение начинается с новой строки |
| 293 | + Результат = Результат + Отступ + СериализованныйКлюч + ":" + Символы.ПС + СериализованноеЗначение; |
| 294 | + КонецЕсли; |
| 295 | + Иначе |
| 296 | + // Простое значение - размещаем на той же строке |
175 | 297 | Результат = Результат + Отступ + СериализованныйКлюч + ": " + СериализованноеЗначение;
|
| 298 | + КонецЕсли; |
176 | 299 | КонецЦикла;
|
177 | 300 |
|
178 | 301 | Возврат Результат;
|
|
299 | 422 | КонецЕсли;
|
300 | 423 |
|
301 | 424 | // Строки, которые могут интерпретироваться как специальные значения YAML
|
| 425 | + // НО только если они точно совпадают |
302 | 426 | СпециальныеЗначения = Новый Массив;
|
303 | 427 | СпециальныеЗначения.Добавить("true");
|
304 | 428 | СпециальныеЗначения.Добавить("false");
|
|
309 | 433 | СпециальныеЗначения.Добавить("on");
|
310 | 434 | СпециальныеЗначения.Добавить("off");
|
311 | 435 |
|
312 |
| - НижнийРегистр = НРег(Значение); |
| 436 | + НижнийРегистр = НРег(СокрЛП(Значение)); |
313 | 437 | Для Каждого СпециальноеЗначение Из СпециальныеЗначения Цикл
|
314 | 438 | Если НижнийРегистр = СпециальноеЗначение Тогда
|
315 | 439 | Возврат Истина;
|
|
0 commit comments