При выгрузке данных в формат XML с использованием внешней компоненты v7plus.dll (объект XMLParser) в среде «1С:Предприятие 7.7» разработчики часто сталкиваются со следующей проблемой. Попытка вручную заменить кавычки в строке на стандартную XML-сущность " приводит к тому, что в итоговом файле вместо ожидаемых кавычек появляется странная конструкция вида ".
Давайте подробно разберем, почему возникает этот эффект «двойного экранирования», как работает стандарт XML в контексте текстовых узлов и какие практические способы решения этой задачи существуют.
Главная ошибка кроется в ручной предобработке строки перед ее передачей в свойство Значение XML-элемента. Рассмотрим типичный ошибочный код:
// Попытка заменить кавычки на " вручную
comments.Значение = СтрЗаменить(НазваниеОрганизации, """", """);
Внешняя компонента v7plus.dll под капотом использует стандартную библиотеку Microsoft MSXML. Эта библиотека строго следует спецификации XML. Согласно правилам консорциума W3C:
" являются абсолютно легальными символами. Их экранирование не требуется. Обязательными к экранированию в этой области являются только символы «меньше» (< превращается в <) и амперсанд (& превращается в &).", парсер видит в строке символ амперсанда (&). Поскольку для XML-парсера это спецсимвол, требующий обязательного экранирования в текстовом поле, он честно заменяет его на &. В результате ваша строка " превращается в файле в &quot;.Таким образом, парсер просто выполняет свою работу по защите структуры документа, предотвращая ручное вмешательство в формирование спецсимволов.
---
Поскольку кавычки внутри тегов XML являются валидными символами, самым правильным и простым решением будет отказаться от ручной замены. Вам нужно передать строку с физическими кавычками напрямую в объект. Парсер запишет их в файл без изменений.
Рассмотрим, как передать кавычки программно, если их изначально нет в переменной:
// Вариант А: Использование удвоенных кавычек в строковом литерале 1С
comments.Значение = """" + НазваниеОрганизации + """";
// Вариант Б: Использование функции Симв(34) для получения символа кавычки
Кавычка = Симв(34);
comments.Значение = Кавычка + НазваниеОрганизации + Кавычка;
В итоговом XML-файле мы получим корректный и валидный тег:
<comments>"ООО Контральт"</comments>
---
Если по какой-то причине принимающая сторона отказывается обрабатывать обычные кавычки в текстовом поле (хотя это стандартное поведение любого XML-декодера) и требует изоляции текста, мы можем использовать секции <![CDATA[...]]>. Внутри таких секций парсеры полностью игнорируют любые спецсимволы, включая кавычки, амперсанды и скобки.
Для создания CDATA-секции в XMLParser необходимо создать подчиненный узел с типом 4 (что соответствует константе NODE_CDATA_SECTION):
// Создаем элемент комментария
comments = invoice.СоздатьПодчиненныйЭлемент("comments");
// Создаем специальный узел CDATA (тип узла - 4)
УзелCDATA = xmlКорень.СоздатьУзел(4, "");
УзелCDATA.Значение = НазваниеОрганизации; // Кавычки здесь будут записаны в исходном виде
// Добавляем созданный CDATA-узел внутрь нашего элемента comments
comments.ДобавитьПодчиненный(УзелCDATA);
На выходе в файле мы получим следующую структуру:
<comments><![CDATA["ООО Контральт"]]></comments>
---
Если информационная система приемника написана некорректно (например, она разбирает XML-файл «самописными» регулярными выражениями вместо стандартного парсера) и жестко требует наличия именно сущностей " внутри тегов, стандартный парсер 1С нам напрямую не поможет. Он всегда будет экранировать амперсанд.
В этом случае мы можем применить хитрость: выгрузить файл стандартным путем (как в Решении 1), а затем открыть его как обычный текст и произвести точечную замену символов.
Проанализируем пример кода для пост-обработки файла:
// Сначала сохраняем XML-документ на диск
ПутьКФайлу = КаталогИБ() + "export.xml";
xmlКорень.Записать(ПутьКФайлу);
// Открываем файл как текстовый документ для точечной замены
ТекстФайла = СоздатьОбъект("Текст");
ТекстФайла.Открыть(ПутьКФайлу);
Для НомерСтроки = 1 По ТекстФайла.КоличествоСтрок() Цикл
ТекущаяСтрока = ТекстФайла.ПолучитьСтроку(НомерСтроки);
// Выполняем замену только в нужных строках, чтобы не испортить служебные кавычки XML-заголовка
Если Найти(ТекущаяСтрока, "<comments>") > 0 Тогда
// Заменяем физическую кавычку Симв(34) на текстовую сущность "
НоваяСтрока = СтрЗаменить(ТекущаяСтрока, Симв(34), """);
ТекстФайла.ЗаменитьСтроку(НомерСтроки, НоваяСтрока);
КонецЕсли;
КонецЦикла;
// Перезаписываем измененный файл
ТекстФайла.Записать(ПутьКФайлу);
---
В современной практике разработки под 1С 7.7 внешняя компонента v7plus.dll часто признается устаревшей. Она требует регистрации в системном реестре Windows, медленно работает с файлами большого объема и может вызывать сбои на 64-разрядных операционных системах.
Альтернативным и крайне надежным решением является ручная сборка структуры XML через встроенный объект Текст. При таком подходе вы получаете абсолютный контроль над каждым записываемым символом и можете расставлять любые сущности без оглядки на ограничения парсера.
Разберем по шагам шаблон ручного формирования XML:
// Создаем текстовый объект
ТекстXML = СоздатьОбъект("Текст");
// Записываем стандартный заголовок документа
ТекстXML.ДобавитьСтроку("<?xml version=""1.0"" encoding=""windows-1251""?>");
ТекстXML.ДобавитьСтроку("<invoice>");
// Формируем значение с принудительной заменой кавычек на "
ПодготовленныйТекст = СтрЗаменить(НазваниеОрганизации, Симв(34), """);
// Добавляем строку с тегом comments
ТекстXML.ДобавитьСтроку(" <comments>" + ПодготовленныйТекст + "</comments>");
ТекстXML.ДобавитьСтроку("</invoice>");
// Сохраняем файл на диск
ПутьКФайлу = КаталогИБ() + "manual_export.xml";
ТекстXML.Записать(ПутьКФайлу);
Этот способ гарантирует получение именно той структуры, которую ожидает ваша принимающая система, исключая любые конфликты с логикой работы компоненты v7plus.dll.