Как добавить новый элемент в структуру XML через СписокЭлементовDOM в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с XML-документами через объектную модель DOM (Document Object Model) в 1С — это мощный инструмент, позволяющий гибко изменять структуру файла, добавлять новые узлы и редактировать атрибуты. Однако начинающие разработчики часто сталкиваются с проблемой при попытке добавить элемент в коллекцию СписокЭлементовDOM. В этой статье мы подробно разберем, почему нельзя добавить элемент напрямую в список и как правильно модифицировать дерево документа.

Понимание проблемы: почему СписокЭлементовDOM не имеет метода Добавить

Рассмотрим ситуацию: мы прочитали XML-документ, нашли группу нужных нам тегов и хотим добавить туда новый узел. Типичная ошибка — пытаться вызвать метод Добавить() или Вставить() непосредственно у объекта СписокЭлементовDOM. Проанализируем причину, по которой это невозможно.

Объект СписокЭлементовDOM (в других языках программирования известный как NodeList) является итерируемой коллекцией, которая представляет собой результат поискового запроса (например, после вызова метода ПолучитьЭлементыПоИмени). Этот список предназначен только для чтения и отражает текущее состояние дерева документа. Чтобы новый элемент «появился» в этом списке, его нужно добавить физически в дерево DOM к конкретному родительскому узлу.

Пошаговое решение: добавление элемента в узел из списка

Для того чтобы добавить новый элемент в структуру, нам необходимо выполнить последовательность действий. Разберем этот процесс по шагам.

  1. Получаем список узлов: Используем метод ПолучитьЭлементыПоИмени или поиск по XPath.
  2. Выбираем конкретный узел: Из полученного списка выбираем нужный элемент по индексу (например, первый элемент [0]).
  3. Создаем новый элемент: Используем метод документа СоздатьЭлемент.
  4. Добавляем элемент к родителю: Используем метод ДобавитьДочерний у выбранного ранее узла.

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


// 1. Создаем построитель и читаем XML
ОбъектXML = Новый ЧтениеXML;
ОбъектXML.УстановитьСтроку(Вложение.XMLДокумента);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ОбъектXML);

// 2. Получаем коллекцию элементов по имени тега
СписокУзлов = ДокументDOM.ПолучитьЭлементыПоИмени("ИнфПолФХЖ1");

// Проверяем, что список не пуст
Если СписокУзлов.Количество() > 0 Тогда
    // 3. Извлекаем конкретный узел (родителя) из списка
    РодительскийЭлемент = СписокУзлов[0];
    
    // 4. Создаем новый элемент, который хотим вставить
    НовыйЭлемент = ДокументDOM.СоздатьЭлемент("ТекстИнф");
    НовыйЭлемент.УстановитьАтрибут("Идентиф", "ЗаказКлиентаНомер");
    НовыйЭлемент.УстановитьАтрибут("Значен", "12345");
    
    // 5. Добавляем созданный элемент в дерево
    РодительскийЭлемент.ДобавитьДочерний(НовыйЭлемент);
КонецЕсли;

Массовое добавление элементов в цикле

Часто возникает задача добавить информацию в каждый элемент определенной коллекции. Например, если нам нужно добавить сведения о товаре (ИнфПолФХЖ2) во все узлы СведТов. Рассмотрим, как это реализовать через обход коллекции СписокЭлементовDOM:


НужныйСписок = ДокументDOM.ПолучитьЭлементыПоИмени("СведТов");

Для Каждого ЭлементСписка Из НужныйСписок Цикл
    // Для каждого существующего узла создаем свой подчиненный узел
    ДопИнфо = ДокументDOM.СоздатьЭлемент("ИнфПолФХЖ2");
    ДопИнфо.УстановитьАтрибут("Идентиф", "Артикул");
    ДопИнфо.УстановитьАтрибут("Значен", "SKU-001");
    
    // Добавляем к текущему элементу итерации
    ЭлементСписка.ДобавитьДочерний(ДопИнфо);
КонецЦикла;

Продвинутые методы манипуляции узлами

Рассмотрим дополнительные возможности 1С при работе с DOM, которые сделают ваш код более надежным и гибким:

  1. Использование XPath для точного поиска: Вместо ПолучитьЭлементыПоИмени, который ищет теги по всему документу, используйте РазыскатьУзлы(). Это позволит найти, например, только те узлы, которые находятся по строго определенному пути или имеют конкретные атрибуты.
  2. Вставка в произвольное место: Метод ДобавитьДочерний всегда помещает узел в конец списка детей. Если вам нужно вставить элемент в начало или перед определенным тегом, используйте метод ВставитьПеред(НовыйУзел, УзелПередКоторымВставить).
  3. Работа с текстовым содержимым: Если данные должны быть не в атрибуте, а внутри тега (<Тег>Данные</Тег>), необходимо создать текстовый узел:
    
    ТекстовыйУзел = ДокументDOM.СоздатьТекст("МоеЗначение");
    НовыйЭлемент.ДобавитьДочерний(ТекстовыйУзел);
    
  4. Клонирование узлов: Если вам нужно создать копию уже существующего в документе сложного узла, используйте КлонироватьУзел(Истина). Параметр Истина означает «глубокое копирование» вместе со всеми вложенными элементами и атрибутами.

Важные замечания по пространствам имен (Namespaces)

Выясним одну важную причину, по которой поиск элементов может не работать. Если ваш XML содержит атрибуты xmlns (пространства имен), обычный метод ПолучитьЭлементыПоИмени может вернуть пустой результат. В таких случаях мы рекомендуем использовать методы с суффиксом NS:

Проанализируем ситуацию: при работе с электронными счетами-фактурами (ЭДО) использование пространств имен является обязательным требованием. Без указания корректного URI пространства имен созданные вами элементы могут быть проигнорированы принимающей стороной.

Завершение работы и сохранение

После того как все манипуляции с деревом ДокументDOM завершены, его необходимо преобразовать обратно в строку или файл. Для этого мы используем связку ЗаписьDOM и ЗаписьXML:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();

ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьDOM.Записать(ДокументDOM, ЗаписьXML);

РезультатXML = ЗаписьXML.Закрыть();

Резюмируем: Для добавления элемента в СписокЭлементовDOM, нужно сначала обратиться к конкретному элементу этого списка как к объекту типа ЭлементDOM, а затем вызвать у него метод ДобавитьДочерний(), предварительно создав новый узел через сам объект ДокументDOM.

← На главную