Как программно изменить значение атрибута в XML-файле или строке в 1С?

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

При разработке интеграционных механизмов программисты часто сталкиваются с необходимостью модификации XML-данных «на лету». Задача может казаться простой, если нужно заменить одну строку на другую, но она значительно усложняется, когда изменение должно происходить строго при соблюдении определенных условий (например, при совпадении значения соседнего атрибута). Рассмотрим подробнее несколько способов решения этой задачи: от самых простых текстовых манипуляций до использования мощных объектных моделей DOM и XPath.

Способ 1. Простая замена текста (метод СтрЗаменить)

Если структура вашего XML проста и вы на 100% уверены, что заменяемое значение уникально и не встречается в других частях файла (в именах тегов, комментариях или других атрибутах), можно воспользоваться самым быстрым способом — чтением файла как обычного текста.

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


// Читаем весь файл в одну строку
Текст = Новый ЧтениеТекста("C:\file.xml", КодировкаТекста.UTF8);
Содержимое = Текст.Прочитать();
Текст.Закрыть();

// Выполняем замену значения
НовоеСодержимое = СтрЗаменить(Содержимое, "1234", "2345");

// Записываем обновленную строку обратно в файл
Запись = Новый ЗаписьТекста("C:\file.xml", КодировкаТекста.UTF8);
Запись.Записать(НовоеСодержимое);
Запись.Закрыть();

Важное замечание: Мы крайне не рекомендуем использовать этот метод для сложных интеграций. Главная опасность СтрЗаменить заключается в том, что она может случайно повредить структуру XML или изменить данные там, где это не планировалось. Используйте этот способ только для разовых правок простых файлов.

Способ 2. Использование объектной модели DOM (ПостроительDOM)

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

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


// 1. Читаем исходный XML
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл("C:\file.xml");

ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();

// 2. Ищем нужные узлы (например, все элементы "Item")
СписокУзлов = ДокументDOM.ПолучитьЭлементыПоИмени("Item");

Для Каждого ТекущийУзел Из СписокУзлов Цикл
    // Проверяем условие: значение атрибута "id_i" должно быть равно "1234"
    АтрибутID = ТекущийУзел.Атрибуты.ПолучитьИмя("id_i");
    Если АтрибутID <> Неопределено И АтрибутID.ЗначениеУзла = "1234" Тогда
        // Если условие выполнено, меняем другой атрибут "id_e"
        АтрибутTarget = ТекущийУзел.Атрибуты.ПолучитьИмя("id_e");
        Если АтрибутTarget <> Неопределено Тогда
            АтрибутTarget.ЗначениеУзла = "2345";
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

// 3. Сохраняем измененный DOM обратно в файл
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\file.xml", "UTF-8");

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

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

Способ 3. Работа с COM-объектом MSXML

Иногда данные приходят из внешних систем в виде COM-объектов, например, MSXML2.DOMDocument. В этом случае мы можем использовать методы самого Windows-компонента. Посмотрим, как это реализовать, если объект уже загружен.


// Допустим, ОбъектXML — это уже существующий COMObject("MSXML2.DOMDocument")
// Используем XPath для точного поиска узла без циклов
Узел = ОбъектXML.selectSingleNode("//element[@id_i='1234']");

Если Узел <> Неопределено Тогда
    // Меняем значение атрибута
    Узел.setAttribute("id_e", "2345");
    // Если нужно получить строку с результатом:
    РезультатСтрокой = ОбъектXML.xml;
КонецЕсли;

Проанализируем ситуацию: использование XPath (запрос //element[@id_i='1234']) позволяет мгновенно найти нужный узел, минуя вложенные циклы Для каждого. Это значительно повышает производительность кода, особенно если XML-структура имеет большую вложенность.

Способ 4. Последовательное чтение и запись (для больших файлов)

Если ваш XML-файл весит несколько сотен мегабайт, использование ПостроительDOM может привести к ошибке нехватки оперативной памяти, так как он загружает всё дерево целиком. В таких случаях мы рекомендуем использовать «потоковый» метод: одновременно открываем один файл на чтение, а второй — на запись.

Рассмотрим логику этого процесса:

  1. Создаем ЧтениеXML для исходного файла.
  2. Создаем ЗаписьXML для нового (временного) файла.
  3. В цикле Пока ЧтениеXML.Прочитать() копируем каждый узел из источника в приемник.
  4. Когда встречаем нужный элемент или атрибут — подменяем его значение в методе записи.
  5. После завершения закрываем оба потока и заменяем старый файл новым.

Рекомендации по кодировкам и формату

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

Выяснив причину сложности задачи (необходимость сохранения изменений после правки DOM), мы видим, что наиболее универсальным инструментом в 1С является связка ПостроительDOM + ЗаписьDOM. Она обеспечивает баланс между удобством разработки и надежностью результата.

← На главную