Работа с XML-файлами — одна из наиболее частых задач при организации обмена данными между 1С и внешними системами. Одной из первых трудностей, с которой сталкиваются разработчики, является формирование правильной «шапки» или декларации документа. В этой статье мы подробно разберем, как использовать объект ЗаписьXML, почему стандартные методы могут выдавать ошибки и как добиться нужного формата строки <?xml version="1.0" encoding="UTF-8"?>.
Рассмотрим ситуацию, возникшую в обсуждении. Разработчик пытался вставить текст декларации напрямую в метод: ИсточникДанные.ЗаписатьОбъявлениеXML("?xml version=""1.0""?");. Это приводило к ошибке, так как в 1С метод ЗаписатьОбъявлениеXML() является процедурой без параметров. Проанализируем, как работает этот механизм внутри платформы.
Платформа 1С берет на себя управление синтаксисом XML. Когда вы вызываете ЗаписатьОбъявлениеXML(), система сама генерирует строку декларации, основываясь на том, как был инициализирован объект ЗаписьXML. Вам не нужно (и нельзя) указывать кавычки или версию вручную внутри этого метода.
Разберем по шагам правильный алгоритм создания XML-документа. Для того чтобы в начале файла появилась корректная строка с указанием версии и кодировки, необходимо выполнить следующую последовательность действий:
ЗаписьXML.ЗаписатьОбъявлениеXML() без каких-либо аргументов.Посмотрим на пример кода, который решает задачу стандартным способом:
ИсточникДанные = Новый ЗаписьXML();
// Указываем путь к файлу и кодировку. Именно отсюда 1С возьмет данные для заголовка.
ИсточникДанные.ОткрытьФайл("C:\Exchange\data.xml", "UTF-8");
// Метод сам запишет <?xml version="1.0" encoding="UTF-8"?>
ИсточникДанные.ЗаписатьОбъявлениеXML();
// Далее записываем корневой элемент
ИсточникДанные.ЗаписатьНачалоЭлемента("Root");
ИсточникДанные.ЗаписатьКонецЭлемента();
// Обязательно закрываем файл для сохранения данных
ИсточникДанные.ЗакрытьФайл();
Иногда внешние системы требуют наличия в заголовке XML специфических параметров, которые не предусмотрены стандартом (например, voprosy="eto moi voprosy", как упоминалось в сообщении форума). Стандартный метод ЗаписатьОбъявлениеXML() этого сделать не позволит, так как он строго следует спецификации W3C.
Выясним причину: согласно спецификации XML, декларация может содержать только атрибуты version, encoding и standalone. Если вам жизненно необходимо нарушить стандарт или вставить специфическую строку в начало файла, мы можем воспользоваться методом ЗаписатьБезОбработки(). Этот метод позволяет вставить произвольный текст напрямую в поток записи.
Проанализируем пример использования этого «обходного» пути:
ИсточникДанные = Новый ЗаписьXML();
ИсточникДанные.ОткрытьФайл(ИмяФайла, "UTF-8");
// Вместо стандартного метода пишем строку вручную
ТекстЗаголовка = "<?xml version=""1.0"" encoding=""UTF-8"" voprosy=""moi voprosy""?>";
ИсточникДанные.ЗаписатьБезОбработки(ТекстЗаголовка);
// Продолжаем работу в обычном режиме
ИсточникДанные.ЗаписатьНачалоЭлемента("Catalog");
ИсточникДанные.ЗаписатьКонецЭлемента();
ИсточникДанные.ЗакрытьФайл();
Важный момент: Использование ЗаписатьБезОбработки() требует от разработчика внимательности к кавычкам. В языке 1С двойные кавычки внутри строки экранируются еще одними двойными кавычками.
Если под «вопросами» в строке понимаются не атрибуты самой декларации, а дополнительные инструкции (например, для подключения XSL-стилей), в 1С предусмотрен специальный метод ЗаписатьИнструкциюОбработки(). Рассмотрим подробнее, как это работает.
Инструкции обработки имеют вид <?Имя Данные?>. Посмотрим на пример кода, который добавляет такую инструкцию сразу после основного заголовка:
ИсточникДанные = Новый ЗаписьXML();
ИсточникДанные.УстановитьСтроку(); // Запись в память (строку)
ИсточникДанные.ЗаписатьОбъявлениеXML();
// Добавляем инструкцию обработки
ИсточникДанные.ЗаписатьИнструкциюОбработки("xml-stylesheet", "type=""text/xsl"" href=""mystyle.xsl""");
ИсточникДанные.ЗаписатьНачалоЭлемента("Data");
ИсточникДанные.ЗаписатьКонецЭлемента();
Результат = ИсточникДанные.Закрыть();
Часто новички сталкиваются с тем, что файл вроде бы сформирован верно, но принимающая сторона его «не видит» или выдает ошибку в первой позиции. Выясним причину этой ситуации. При записи в UTF-8 платформа 1С может добавлять невидимые символы — метку BOM.
Если вам нужно записать XML строго без BOM, рекомендуем использовать связку объектов ЗаписьТекста и ЗаписьXML. Разберем по шагам, как это реализовать:
ЗаписьТекста, где в параметрах конструктора явно указываем ИспользованиеBOM.НеИспользовать.ОткрытьПоток() объекта ЗаписьXML.
// 1. Готовим поток записи текста без BOM
ЗаписьТекста = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8, , , ИспользованиеBOM.НеИспользовать);
// 2. Инициализируем ЗаписьXML через этот поток
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.ОткрытьПоток(ЗаписьТекста);
// 3. Теперь записываем объявление
ЗаписьXML.ЗаписатьОбъявлениеXML();
// В итоге получим чистый файл без лишних символов в начале
ЗаписьXML.Закрыть();
ЗаписьТекста.Закрыть();
Мы проанализировали различные способы формирования заголовка XML в 1С. Подведем итоги:
ЗаписатьОбъявлениеXML() без параметров.ОткрытьФайл().ЗаписатьБезОбработки(), но помните о риске создания невалидного XML.Закрыть() или ЗакрытьФайл(), иначе данные не будут записаны на диск полностью.Соблюдение этих простых правил позволит вам избежать большинства ошибок, связанных с сериализацией данных в формат XML, и обеспечит совместимость ваших выгрузок с любыми внешними информационными системами.