Skip to content

Commit 27c0a7a

Browse files
committed
Основной класс библиотеки
1 parent b225262 commit 27c0a7a

File tree

1 file changed

+363
-0
lines changed

1 file changed

+363
-0
lines changed
Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
#Использовать logos
2+
3+
Перем Лог;
4+
Перем ИмяПоследнегоАтрибута;
5+
Перем УпроститьЭлементы;
6+
7+
Процедура ПриСозданииОбъекта(Упростить = Истина)
8+
9+
УпроститьЭлементы = Истина;
10+
11+
Если ЗначениеЗаполнено(Упростить) Тогда
12+
УпроститьЭлементы = Упростить;
13+
КонецЕсли;
14+
15+
Лог = Логирование.ПолучитьЛог("oscript.lib.xml-parser");
16+
17+
КонецПроцедуры
18+
19+
// Выполняет чтение данных xml в соответствие
20+
//
21+
// Параметры:
22+
// ПутьКФайлу - Строка - путь к файлу с данными xml
23+
//
24+
// Возвращаемое значение:
25+
// Соответствие, Структура - результат чтения данных xml
26+
//
27+
Функция ПрочитатьИзФайла(Знач ПутьКФайлу) Экспорт
28+
29+
Чтение = Новый ЧтениеXML;
30+
Чтение.ОткрытьФайл(ПутьКФайлу);
31+
32+
Результат = ПрочитатьXML(Чтение);
33+
34+
Чтение.Закрыть();
35+
36+
Возврат Результат;
37+
38+
КонецФункции
39+
40+
// Выполняет сериализацию данных в файла
41+
//
42+
// Параметры:
43+
// ДанныеЗаписиXML - Соответствие, Массив, Структура, Число, Строка. Дата - данные для сериализации в XML
44+
// ПутьКФайлу - Строка - путь к файлу с данными xml
45+
// ЗаписатьОбъявлениеXML - Булево - признак добавления записи объявления XML
46+
//
47+
Процедура ЗаписатьВФайл(ДанныеЗаписиXML, Знач ПутьКФайлу, Знач ЗаписатьОбъявлениеXML = Ложь) Экспорт
48+
49+
ЗаписьXML = Новый ЗаписьXML;
50+
ЗаписьXML.ОткрытьФайл(ПутьКФайлу);
51+
52+
Если ЗаписатьОбъявлениеXML Тогда
53+
ЗаписьXML.ЗаписатьОбъявлениеXML();
54+
КонецЕсли;
55+
56+
ЗаписатьXML(ЗаписьXML, ДанныеЗаписиXML);
57+
58+
ЗаписьXML.Закрыть();
59+
60+
КонецПроцедуры
61+
62+
// Выполняет чтение и десериализацию данных из XML
63+
//
64+
// Параметры:
65+
// ЧтениеXML - ЧтениеXML - <описание параметра>
66+
// ИмяКорневогоУзла - Строка - имя текущего узла, для вызова рекурсии
67+
//
68+
// Возвращаемое значение:
69+
// Соответствие, Структура - результат чтения данных xml
70+
//
71+
Функция ПрочитатьXML(Знач ЧтениеXML, Знач ИмяКорневогоУзла = "") Экспорт
72+
73+
РезультатЧтения = Новый Структура;
74+
Атрибуты = Новый Соответствие;
75+
Элементы = Новый Соответствие;
76+
77+
РезультатЧтения.Вставить("_Атрибуты", Атрибуты);
78+
РезультатЧтения.Вставить("_Элементы", Элементы);
79+
80+
Лог.Отладка("Начинаю чтение узла <%1> из XML.", ЧтениеXML.ЛокальноеИмя);
81+
82+
ПрочитатьАтрибуты(ЧтениеXML, Атрибуты);
83+
84+
Если Не ЧтениеXML.ТипУзла = ТипУзлаXML.КонецСущности Тогда
85+
ПрочитатьУзлы(ЧтениеXML, РезультатЧтения, ИмяКорневогоУзла);
86+
КонецЕсли;
87+
88+
УпроститьРезультатЧтения(РезультатЧтения);
89+
90+
Лог.Отладка("Чтение узла <%1> закончено.", ЧтениеXML.ЛокальноеИмя);
91+
92+
Возврат РезультатЧтения;
93+
94+
КонецФункции
95+
96+
// Выполняет сериализацию данных в XML
97+
//
98+
// Параметры:
99+
// ЗаписьXML - ЗаписьXML - подготовленная запись ЗаписьXML
100+
// ДанныеЗаписиXML - Соответствие, Массив, Структура, Число, Строка. Дата - данные для сериализации в XM
101+
//
102+
Процедура ЗаписатьXML(Знач ЗаписьXML, Знач ДанныеЗаписиXML) Экспорт
103+
104+
ЗаписатьЗначениеXML(ЗаписьXML, ДанныеЗаписиXML);
105+
106+
КонецПроцедуры
107+
108+
#Область Запись_данных_XML
109+
110+
Процедура ЗаписатьЗначениеXML(Знач ЗаписьXML, Знач ДанныеЗаписиXML, Знач ИмяКорневогоУзла = "")
111+
112+
НачатьЗаписьЭлемента = НЕ ПустаяСтрока(ИмяКорневогоУзла);
113+
114+
Если НачатьЗаписьЭлемента Тогда
115+
ЗаписьXML.ЗаписатьНачалоЭлемента(XMLСтрока(ИмяКорневогоУзла));
116+
КонецЕсли;
117+
118+
ТипДанныеЗаписиXML = ТипЗнч(ДанныеЗаписиXML);
119+
120+
Если ТипДанныеЗаписиXML = Тип("Массив") Тогда
121+
ЗаписатьМассивВXML(ЗаписьXML, ДанныеЗаписиXML);
122+
ИначеЕсли ТипДанныеЗаписиXML = Тип("Соответствие")
123+
ИЛИ ТипДанныеЗаписиXML = Тип("Структура") Тогда
124+
ЗаписатьСоответствиеВXML(ЗаписьXML, ДанныеЗаписиXML);
125+
ИначеЕсли ЭтоПростойТип(ТипДанныеЗаписиXML) Тогда
126+
127+
ЗаписатьТекст(ЗаписьXML, ДанныеЗаписиXML);
128+
129+
КонецЕсли;
130+
131+
Если НачатьЗаписьЭлемента Тогда
132+
ЗаписьXML.ЗаписатьКонецЭлемента();
133+
КонецЕсли;
134+
135+
КонецПроцедуры
136+
137+
Функция ЭтоПростойТип(Знач ТипДанных)
138+
139+
Возврат ТипДанных = Тип("Число")
140+
ИЛИ ТипДанных = Тип("Строка")
141+
ИЛИ ТипДанных = Тип("Булево")
142+
;
143+
144+
КонецФункции
145+
146+
Процедура ЗаписатьАтрибуты(ЗаписьXML, ДанныеАтрибутов)
147+
148+
Если ДанныеАтрибутов.Количество() = 0 Тогда
149+
Возврат;
150+
КонецЕсли;
151+
152+
Для каждого КлючЗначение Из ДанныеАтрибутов Цикл
153+
154+
ЗаписьXML.ЗаписатьАтрибут(XMLСтрока(КлючЗначение.Ключ), XMLСтрока(КлючЗначение.Значение));
155+
156+
КонецЦикла;
157+
158+
КонецПроцедуры
159+
160+
Процедура ЗаписатьСекцияCDATA(ЗаписьXML, ДанныеСекцияCDATA)
161+
162+
Если НЕ ЗначениеЗаполнено(ДанныеСекцияCDATA) Тогда
163+
Возврат;
164+
КонецЕсли;
165+
166+
ЗаписьXML.ЗаписатьСекциюCDATA(ДанныеСекцияCDATA);
167+
168+
КонецПроцедуры
169+
170+
Процедура ЗаписатьКомментарий(ЗаписьXML, Комментарий)
171+
172+
Если НЕ ЗначениеЗаполнено(Комментарий) Тогда
173+
Возврат;
174+
КонецЕсли;
175+
176+
ЗаписьXML.ЗаписатьКомментарий(XMLСтрока(Комментарий));
177+
178+
КонецПроцедуры
179+
180+
Процедура ЗаписатьТекст(ЗаписьXML, Текст)
181+
182+
Если НЕ ЗначениеЗаполнено(Текст) Тогда
183+
Возврат;
184+
КонецЕсли;
185+
186+
ЗаписьXML.ЗаписатьТекст(XMLСтрока(Текст));
187+
188+
КонецПроцедуры
189+
190+
Процедура ЗаписатьМассивВXML(ЗаписьXML, Знач ДанныеМассива)
191+
192+
Для каждого ЭлементМассива Из ДанныеМассива Цикл
193+
ЗаписатьЗначениеXML(ЗаписьXML, ЭлементМассива);
194+
КонецЦикла;
195+
196+
КонецПроцедуры
197+
198+
Процедура ЗаписатьСоответствиеВXML(ЗаписьXML, ДанныеСоответствия)
199+
200+
Для каждого КлючЗначение Из ДанныеСоответствия Цикл
201+
202+
Если КлючЗначение.Ключ = "_Атрибуты" Тогда
203+
ЗаписатьАтрибуты(ЗаписьXML, КлючЗначение.Значение);
204+
Продолжить;
205+
КонецЕсли;
206+
207+
Если КлючЗначение.Ключ = "_Комментарий" Тогда
208+
ЗаписатьКомментарий(ЗаписьXML, КлючЗначение.Значение);
209+
Продолжить;
210+
КонецЕсли;
211+
212+
Если КлючЗначение.Ключ = "_CDATA" Тогда
213+
ЗаписатьСекцияCDATA(ЗаписьXML, КлючЗначение.Значение);
214+
Продолжить;
215+
КонецЕсли;
216+
217+
Если КлючЗначение.Ключ = "_Значение" Тогда
218+
ЗаписатьТекст(ЗаписьXML, КлючЗначение.Значение);
219+
Продолжить;
220+
КонецЕсли;
221+
222+
Если КлючЗначение.Ключ = "_Элементы" Тогда
223+
ЗаписатьЗначениеXML(ЗаписьXML, КлючЗначение.Значение);
224+
Продолжить;
225+
КонецЕсли;
226+
227+
ЗаписатьЗначениеXML(ЗаписьXML, КлючЗначение.Значение, КлючЗначение.Ключ);
228+
229+
КонецЦикла;
230+
231+
КонецПроцедуры
232+
233+
#КонецОбласти
234+
235+
#Область Чтение_данных_XML
236+
237+
Процедура УпроститьРезультатЧтения(РезультатЧтения)
238+
239+
Если НЕ УпроститьЭлементы Тогда
240+
Возврат;
241+
КонецЕсли;
242+
243+
Если РезультатЧтения["_Атрибуты"].Количество() = 0 Тогда
244+
РезультатЧтения.Удалить("_Атрибуты");
245+
КонецЕсли;
246+
247+
Если РезультатЧтения["_Элементы"].Количество() = 0 Тогда
248+
РезультатЧтения.Удалить("_Элементы");
249+
КонецЕсли;
250+
251+
МожноУпростить = РезультатЧтения.Количество() = 1;
252+
253+
Если МожноУпростить Тогда
254+
Если РезультатЧтения.Свойство("_Значение") Тогда
255+
РезультатЧтения = РезультатЧтения._Значение;
256+
ИначеЕсли РезультатЧтения.Свойство("_Элементы") Тогда
257+
РезультатЧтения = РезультатЧтения._Элементы;
258+
КонецЕсли;
259+
КонецЕсли;
260+
261+
КонецПроцедуры
262+
263+
Процедура ПрочитатьАтрибуты(Знач ЧтениеXML, Атрибуты)
264+
265+
Если ЧтениеXML.КоличествоАтрибутов() = 0 Тогда
266+
ИмяПоследнегоАтрибута = Неопределено;
267+
Возврат;
268+
КонецЕсли;
269+
270+
Для ИндексАтрибута = 0 По ЧтениеXML.КоличествоАтрибутов() - 1 Цикл
271+
272+
ИмяАтрибута = ЧтениеXML.ИмяАтрибута(ИндексАтрибута);
273+
ЗначениеАтрибута = ЧтениеXML.ЗначениеАтрибута(ИмяАтрибута);
274+
275+
Лог.Отладка("Прочитано значение <%1> атрибута <%2>", ЗначениеАтрибута, ИмяАтрибута);
276+
Атрибуты.Вставить(СокрЛП(ИмяАтрибута), СокрЛП(ЗначениеАтрибута));
277+
ИмяПоследнегоАтрибута = ЧтениеXML.Имя;
278+
КонецЦикла;
279+
280+
КонецПроцедуры
281+
282+
Процедура ПрочитатьУзлы(Знач ЧтениеXML, КорневойУзел, Знач ИмяКорневогоУзла)
283+
284+
Пока ЧтениеXML.Прочитать() Цикл
285+
286+
Лог.Отладка("Тип узла <%1>", ЧтениеXML.ТипУзла);
287+
Лог.Отладка("Имя узла <%1>", ЧтениеXML.ЛокальноеИмя);
288+
289+
Если ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента
290+
И ЧтениеXML.ЛокальноеИмя = ИмяКорневогоУзла Тогда
291+
Прервать;
292+
КонецЕсли;
293+
294+
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
295+
296+
ИмяНовогоУзла = ЧтениеXML.ЛокальноеИмя;
297+
Лог.Отладка("Новый узел <%1>", ИмяНовогоУзла);
298+
СоответствиеУзла = ПрочитатьXML(ЧтениеXML, ИмяНовогоУзла);
299+
ВставитьЭлементУзла(КорневойУзел, ИмяНовогоУзла, СоответствиеУзла);
300+
301+
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
302+
303+
ЗначениеСвойства = ЧтениеXML.Значение;
304+
Лог.Отладка("Прочитано значение " + ЗначениеСвойства);
305+
КорневойУзел.Вставить("_Значение", ЗначениеСвойства);
306+
307+
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Комментарий Тогда
308+
ЗначениеСвойства = ЧтениеXML.Значение;
309+
Лог.Отладка("Прочитан комментарий " + ЗначениеСвойства);
310+
КорневойУзел.Вставить("_Комментарий", ЗначениеСвойства);
311+
312+
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.СекцияCDATA Тогда
313+
ЗначениеСвойства = ЧтениеXML.Значение;
314+
Лог.Отладка("Прочитана СекцияCDATA " + ЗначениеСвойства);
315+
КорневойУзел.Вставить("_CDATA", ЗначениеСвойства);
316+
317+
КонецЕсли;
318+
319+
КонецЦикла;
320+
321+
КонецПроцедуры
322+
323+
Процедура ВставитьЭлементУзла(КорневойУзел, Знач ИмяНовогоУзла, СоответствиеУзла)
324+
325+
ТипЭлементовУзла = ТипЗнч(КорневойУзел._Элементы);
326+
СоответствиеТекущегоЭлемента = Новый Соответствие();
327+
СоответствиеТекущегоЭлемента.Вставить(ИмяНовогоУзла, СоответствиеУзла);
328+
329+
Если ТипЭлементовУзла = Тип("Массив") Тогда
330+
КорневойУзел._Элементы.Добавить(СоответствиеТекущегоЭлемента);
331+
ИначеЕсли ТипЭлементовУзла = Тип("Соответствие") Тогда
332+
333+
УжеЕстьЗначение = НЕ КорневойУзел._Элементы[ИмяНовогоУзла] = Неопределено;
334+
335+
Если УжеЕстьЗначение Тогда
336+
МассивЭлементов = Новый Массив;
337+
338+
Для каждого КлючЗначение Из КорневойУзел._Элементы Цикл
339+
ТекущийЭлемент = Новый Соответствие();
340+
ТекущийЭлемент.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
341+
МассивЭлементов.Добавить(ТекущийЭлемент);
342+
КонецЦикла;
343+
344+
345+
МассивЭлементов.Добавить(СоответствиеТекущегоЭлемента);
346+
347+
КорневойУзел._Элементы = МассивЭлементов;
348+
349+
Иначе
350+
351+
СоответствиеТекущегоЭлемента = Новый Соответствие();
352+
КорневойУзел._Элементы.Вставить(ИмяНовогоУзла, СоответствиеУзла);
353+
354+
КонецЕсли;
355+
Иначе
356+
357+
ВызватьИсключение СтрШаблон("Пришел не корректный тип значения <%1>", ТипЭлементовУзла);
358+
359+
КонецЕсли;
360+
361+
КонецПроцедуры
362+
363+
#КонецОбласти

0 commit comments

Comments
 (0)