Елегантне читання великих xml файлів

У статті показано як елегантно зчитувати великих XML файлів

При необхідності прочитати XML файл можна застосовувати один з підходів: повне завантаження в DOM і послідовне читання. Повне завантаження XML файлу в DOM реалізована в 1C c допомогою об'єкта ДокументDOM. DOM - це класно, але говорити про нього сьогодні не буду, так як мова йде про відносно великих файлах XML, і тут DOM не підходить. Послідовне читання XML файлів реалізовано в 1С за допомогою такого об'єкта як ЧтеніеXML. Є й інші об'єкти в 1С для роботи з XML, але сьогодні, знову ж, не про них.

Об'єкт ЧтеніеXML - яскравий представник підходу послідовного читання XML файлу. Я впевнений, що ви уявляєте як виглядає код з використанням об'єкта ЧтеніеXML. У ньому є цикли і багато умов на порівняння типу і імені вузла. Мені не подобається такий код і я не люблю його писати. Якщо ви не уявляєте як виглядає такий код, то вирішите описану нижче демонстраційну завдання з використанням об'єкта ЧтеніеXML і вам стане зрозуміліше про що я говорю.

На вході файл Контрагенти.xml наступної структури і змісту:

Реалізуємо завантаження контрагентів в обробці "Завантаження контрагентів". При натисканні на кнопку "Завантажити" виконується наступний код:

Спочатку створюється універсальна обробка ЕлегантноеЧтеніеXML і викликається метод Прочитати. Першим аргументом передається ім'я XML файлу. Другим аргументом передається спеціальний об'єкт-делегат. Обробка, читаючи послідовно файл XML, запускає методи об'єкта-делегата при початку читання вузла, завершення читання вузла і деяких інших випадках.

Об'єкт-делегат повинен реалізовувати такі методи:

1. Процедура Початок (ЧтеніеXML) Експорт - дана процедура запускається при початку обробки XML файлу, в ній можна ініціювати якісь змінні і налаштувати об'єкт ЧтеніеXML

2. Функція Завершення () Експорт - дана функція запускається самої останньої, і повинна повернути результат обробки файлу, може повернути і не визначено - це нормально

3. Функція УзелНачало (ЧтеніеXML, Вузол) Експорт - дана функція запускається кожного разу, коли починає оброблятися новий вузол. У параметрі Вузол знаходиться вже зчитана інформація про вузол: локальне ім'я, URI простору імен, таблиця атрибутів і так далі. Параметр ЧтеніеXML передається для того, щоб ви могли самостійно доповнити Вузол потрібними незаповненими властивостями. Ключовий момент - функція повинна повернути Істина, якщо вузол був оброблений в цій функції, і брехня якщо не оброблявся. У разі якщо вузол не оброблявся, то буде викликаний метод УзелНачало (ЧтеніеXML, Вузол), інакше не буде

4. Функція УзелЗавершеніе (Вузол) Експорт - дана функція запускається кожного разу, коли закінчує оброблятися вузол. У параметрі Вузол знаходиться вся необхідна інформація про вузол. Ключовий момент - функція повинна повернути Істина, якщо вузол був оброблений в цій функції, і брехня якщо не оброблявся. У разі якщо вузол не оброблявся, то буде викликаний метод УзелЗавершеніе (Вузол), інакше не буде.

5. Процедура УзелНачало (ЧтеніеXML, Вузол) Експорт - дана процедура запускається кожного разу, коли починає оброблятися вузол з локальним ім'ям Тег, якщо звичайно до цього вузол не був оброблений при виклику УзелНачало (ЧтеніеXML, Вузол)

6. Процедура УзелЗавершеніе (Вузол) Експорт - дана процедура запускається кожного разу, коли закінчує оброблятися вузол з локальним ім'ям Тег, якщо звичайно до цього вузол не був оброблений при виклику УзелЗавершеніе (Вузол)

Параметр Вузол крім того, що містить інформацію про поточний вузлі, він ще посилається на батьківський вузол. Батьківські вузли існують поки обробляються всі його дочірні вузли. Іншими словами отримати доступ до батьківських вузлів ви можете завжди.

У нашому прикладі в якості об'єкта-делегата переданий поточний екземпляр обробки "Завантаження контрагентів", модуль об'єкта якої виглядає наступним чином:

Зверніть увагу, що в наведеному коді немає ні циклів, ні умов на порівняння типу і імені вузла. На мій погляд, він читається дуже легко.

Мені довелося вказувати теги в квадратних дужках, так як кутові "проковтують" інфостартом.

Зауваження 3: Згідно зі специфікацією XML ім'я тега може містити не тільки літери, цифри і знак підкреслення, а ще й інші символи, наприклад "-" або ".". У XML допустимо, наприклад, такий тег [a-b.c]. Тому все неприпустимі для ідентифікатора 1С символи ігноруються, так, для прикладу вище, тег буде оброблений методом УзелABCНачало (ЧтеніеXML, Вузол).

Зауваження 5: Значення вузла, тобто текст який знаходиться між відкриває і закриває тегами, можна отримати як Узел.Значеніе, але зробити це можна тільки при завершенні обробки вузла, тобто в методі УзелЗавершеніе (Вузол) або УзелЗавершеніе (Вузол).

Крім описаних особливостей напевно є й інші.

Упевнений, що поточна реалізація не ідеальна, але я і не ставив перед собою таке завдання. Я лише хотів продемонструвати підхід, який мені здається елегантним.

Якщо залишилися питання, то завантажуйте ЕлегантноеЧтеніеXML.cf

Дякуємо за увагу.

11. Андрій Овсянкин (Evil Beaver) 4341 08.10.14 18:47 Зараз в темі

(5) rtnm, мінус за велосипед, виданий за якесь елегантне читання. Мінус за те, що цей підхід пропагується серед спільноти, замість того, щоб підштовхувати новачків до вивчення менш велосипедних рішень.

budunovmv; alexscamp; Ivon; YPermitin; нормальний такий; IvanBoychuk123; baton_pk; zqzq; DrAku1a; 1cWin; rtnm; + 11 - Відповісти

6. Олександр *** (a1ex4ndr) 08.10.14 13:11 Зараз в темі

А на якому розмірі файлу тестувалося? А то в тесті файл з трьох рядків.

7. rtnm rtnm (rtnm) 542 08.10.14 13:13 Зараз в темі

(6) a1ex4ndr, Справа не в розмірі файлу, а в підході - послідовне читання. Ніяких чудес не буде, все можна порівняти з ЧтеніеXML.

8. DUH Technolover (DJDUH) 16 08.10.14 13:46 Зараз в темі

9. rtnm rtnm (rtnm) 542 08.10.14 14:01 Зараз в темі

10. DAnry (DAnry) 12 08.10.14 15:38 Зараз в темі

Мені теж подобається. Плюсанул.

12. Володимир Казначеєв (Mogidin) 123 09.10.14 13:27 Зараз в темі

то ж ЧтеніеXML, але набагато швидше

15. Костянтин Юрін (kostyaomsk) 72 23.10.14 10:23 Зараз в темі

16. Андрій Овсянкин (Evil Beaver) 4341 28.10.14 17:01 Зараз в темі

(12) Mogidin, че, прям набагато? А цифри є?

13. Дмитро Нікс (aximo) 668 09.10.14 19:17 Зараз в темі

До речі, Ви реально працювали з великими XML-файлами? Справа в тому, що при збереження тексту розмітки на УФ більше 10 мб (з досвіду) платформа 8.2 може видавати помилку збереження файлу.

14. rtnm rtnm (rtnm) 542 09.10.14 22:48 Зараз в темі

(13) aximo, з великими XML-файлами разом з УФ не працював

17. DrZombi DrZombi (DrZombi) 05.11.14 15:52 Зараз в темі


п.с. на DBF теж можна організовувати древа, але накой воно треба;)

18. rtnm rtnm (rtnm) 542 05.11.14 17:08 Зараз в темі

(17) DrZombi, наступного разу так і скажи замовнику: "Ваш XML відстій. Дайте мені DBF, мені з ним куди приємніше працювати" :)

19. Костянтин Юрін (kostyaomsk) 72 14.11.14 20:47 Зараз в темі

Найнеприємніше в форматі DBF це довга текстового поля (боюся помилитися) 254 символу і потім вже засобами 1С доводиться склеювати рядки або під час вивантаження в DBF дробити на частини. Причому сам формат DBF останніх редакцій може і підтримувати поле МЕМО (рядок необмеженої довжини), а ось в 1С об'єкт XBase вже немає.
Сенс використовувати dbf якщо тільки стороння АІС типу paradox (foxPro, 1С 7.7 в файловому режимі) його генерує для обміну (або завантажують в неї) або це і є зовнішнє джерело даних.

Созданіе02.10.14 9:55

Обновленіе02.10.14 9:55

Код откритНе вказано

Елегантне читання великих xml файлів

Елегантне читання великих xml файлів

Елегантне читання великих xml файлів

Елегантне читання великих xml файлів

Схожі статті