Как получить XML в строке без сохранения в файл в 1С 7.7 с помощью v7plus.dll

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции систем автоматизации на платформе 1С:Предприятие 7.7 с внешними Web-сервисами, API или шлюзами отправки данных (такими как СБИС, EDI, государственные информационные системы) разработчики часто сталкиваются с необходимостью формирования XML-пакетов. Стандартный подход, предлагаемый во многих старых руководствах, подразумевает формирование структуры и её запись на диск с помощью метода Записать(). Однако постоянное обращение к жесткому диску или сетевым папкам существенно снижает производительность системы, создает лишний мусор во временных каталогах и может вызывать ошибки блокировки файлов при многопользовательской работе.

В этой статье мы подробно разберем, как получить готовый XML-документ прямо в текстовую переменную 1С 7.7 в памяти компьютера без записи на диск, используя как штатную внешнюю компоненту v7plus.dll, так и более современные системные альтернативы.

Решение проблемы с помощью v7plus.dll: свойство ПредставлениеXML

Основная сложность, с которой сталкиваются программисты при работе с объектом AddIn.XMLParser из библиотеки v7plus.dll, заключается в неочевидности его программной структуры. Метод выгрузки в файл хорошо задокументирован, в то время как свойства для извлечения сырого текста кажутся отсутствующими. Попытка обратиться к интуитивному свойству вроде XMLДокумент.Текст не приносит желаемого результата.

Выясним причину этого поведения. Дело в том, что объект «Документ» в модели XML наследует свойства базового объекта «Узел» (Node). Именно на уровне базового узла в компоненте v7plus.dll определено специальное свойство ПредставлениеXML. Поскольку документ сам по себе является корневым узлом дерева, мы можем напрямую прочитать это свойство у всего документа.

Давайте рассмотрим пример кода, который решает эту задачу:


// Создаем парсер и документ XML
XMLParser = СоздатьОбъект("AddIn.XMLParser");
XMLДокумент = XMLParser.СоздатьДокумент();

// Производим наполнение документа элементами
КорневойУзел = XMLДокумент.СоздатьПодчиненныйУзел("RootElement");
НовыйУзел = КорневойУзел.СоздатьПодчиненныйУзел("SubElement");
НовыйУзел.Значение = "Пример передаваемых данных";

// Получаем XML в виде текстовой строки напрямую из памяти
СтрокаXML = XMLДокумент.ПредставлениеXML;

// Теперь строку СтрокаXML можно передать в HTTP-запрос
Предупреждение(СтрокаXML);

Важный нюанс: формирование XML-декларации (заголовка)

При использовании свойства ПредставлениеXML библиотека v7plus.dll возвращает только структуру самих тегов, часто упуская стандартный заголовок разметки (декларацию вида <?xml version="1.0" encoding="..."?>). Большинство современных веб-сервисов при отправке им POST-запроса без этого заголовка вернут ошибку парсинга (Bad Request).

Проанализируем ситуацию и добавим решение по формированию корректного заголовка в нужной кодировке вручную. Мы можем принудительно задать кодировку объекту документа, а затем склеить результирующую строку:


КодировкаХМЛ = "windows-1251"; // Используйте "utf-8" или "windows-1251" в зависимости от требований API
XMLДокумент.Кодировка = КодировкаХМЛ;

// Собираем валидный XML-пакет вручную
ЗаголовокXML = "<?xml version=""1.0"" encoding=""" + КодировкаХМЛ + """ standalone=""yes""?>";
ИтоговыйПакетДляОтправки = ЗаголовокXML + XMLДокумент.ПредставлениеXML;

Обратная задача: загрузка XML из строки без использования файлов

Разберем зеркальную ситуацию. Что делать, если сервер прислал вам текстовый ответ в формате XML, и его требуется распарсить обратно в структуру 1С 7.7, избегая сохранения во временные файлы? Для этого в v7plus.dll существует эффективный, но редко упоминаемый метод ЗагрузитьИзСтроки().

Посмотрим на пример его реализации:


// Предположим, что в переменной ПолученныйТекстОтвета хранится строка с XML
XMLParser = СоздатьОбъект("AddIn.XMLParser");
XMLДокумент = XMLParser.СоздатьДокумент();

Попытка
    XMLДокумент.ЗагрузитьИзСтроки(ПолученныйТекстОтвета);
    // Начинаем обход дерева XML
    КорневойУзел = XMLДокумент.ПолучитьПодчиненныйУзел("RootElement");
    // Дальнейшая обработка данных...
Исключение
    Сообщить("Ошибка парсинга XML-строки: " + ОписаниеОшибки(), "!");
КонецПопытки;

Альтернативный и более надежный метод: использование MSXML2.DOMDocument

Хотя использование v7plus.dll решает поставленную задачу, профессиональные разработчики 1С 7.7 рекомендуют полностью отказаться от этой внешней компоненты в пользу системного COM-объекта MSXML2.DOMDocument. Давайте разберем причины, по которым этот переход считается оправданным:

  1. Проблемы совместимости: Компонента v7plus.dll является 32-битной библиотекой и часто вызывает сбои при регистрации в реестре операционных систем Windows 10, Windows 11 и Windows Server последних версий. Требуются права администратора и ручной запуск regsvr32.
  2. Утечки памяти: При работе с большими массивами данных (например, выгрузка тысяч накладных) парсер v7plus подвержен утечкам оперативной памяти, что может приводить к аварийному закрытию платформы 1С 7.7.
  3. Поддержка стандартов: Системная библиотека MSXML2, поставляемая корпорацией Microsoft в составе ОС Windows, регулярно обновляется, гораздо стабильнее работает со сложными пространствами имен (Namespaces) и кодировкой UTF-8.

Давайте посмотрим, как переписать логику формирования XML-строки без файлов с использованием системного объекта MSXML2.DOMDocument:


// Создаем системный COM-объект DOM-документа
DOMДокумент = СоздатьОбъект("MSXML2.DOMDocument");

// Создаем декларацию (заголовок) XML
Декларация = DOMДокумент.createProcessingInstruction("xml", "version=""1.0"" encoding=""windows-1251""");
DOMДокумент.appendChild(Декларация);

// Создаем корневой элемент
КорневойЭлемент = DOMДокумент.createElement("RootElement");
DOMДокумент.appendChild(КорневойЭлемент);

// Добавляем подчиненные узлы
НовыйУзел = DOMДокумент.createElement("SubElement");
НовыйУзел.text = "Пример текста в кодировке MSXML";
КорневойЭлемент.appendChild(НовыйУзел);

// Получаем XML в виде готовой строки без каких-либо временных файлов
СтрокаXML = DOMДокумент.xml;

// Строка готова для передачи в HTTP-запрос
Сообщить(СтрокаXML);

Для загрузки XML из строки обратно в объект MSXML2.DOMDocument используется метод loadXML(), который работает мгновенно и прямо в памяти:


DOMДокумент = СоздатьОбъект("MSXML2.DOMDocument");
// Загружаем XML-строку напрямую в парсер
УспешноЗагружено = DOMДокумент.loadXML(СтрокаСПолученнымXML);

Если УспешноЗагружено = 0 Тогда
    Сообщить("Ошибка разбора XML: " + DOMДокумент.parseError.reason, "!");
Иначе
    // Читаем данные из загруженной структуры
    ЗначениеЭлемента = DOMДокумент.selectSingleNode("//SubElement").text;
    Сообщить("Получено значение: " + ЗначениеЭлемента);
КонецЕсли;

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

← На главную