Как исправить ошибки преобразования данных XDTO и правильно настроить чтение и запись XML в 1С

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

Работа с XDTO (XML Data Transfer Objects) в 1С часто вызывает трудности у разработчиков, особенно когда структура XML не идеально совпадает с ожидаемой XSD-схемой. Распространенные ошибки, такие как "Проверка дополнительного свойства" или "Структура объекта не соответствует типу", могут поставить в тупик даже опытного специалиста. В этой статье мы разберем основные причины возникновения этих ошибок, рассмотрим механизмы работы Фабрики XDTO и научимся правильно формировать и читать XML-файлы.

Разбор ошибки «Проверка дополнительного свойства»

Проанализируем ситуацию, когда при выполнении метода ПрочитатьXML платформа выдает ошибку преобразования. Это происходит в тот момент, когда парсер 1С встречает в файле элемент, который не описан в свойствах типа в вашем XDTO-пакете. Рассмотрим основные причины:

  1. Несоответствие пространства имен: Если в XML-файле указано пространство имен (namespace), которое отсутствует в вашей фабрике, 1С не сможет сопоставить данные с объектом.
  2. Попытка прочитать HTML как XML: Очень часто внешние сервисы при ошибке или неверном запросе возвращают стандартную HTML-страницу (например, ошибку 404 или 500). Платформа пытается интерпретировать теги <html> или <body> как данные XML, что и приводит к ошибке «Элемент имя: {».
  3. Проблемы с URI схемы: Если в пакете XDTO указана директива импорта с URL-адресом, 1С может попытаться скачать схему по этой ссылке. Если сервер по этому адресу недоступен или отдает HTML-страницу, фабрика инициализируется некорректно.

Как правильно читать XML через Фабрику XDTO

Для корректного чтения данных нам необходимо сначала определить тип объекта, который мы ожидаем получить. Выясним, как сделать это программно, используя объект ЧтениеXML. Рассмотрим пример кода для разбора ответа от веб-сервиса:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);

// Пытаемся получить тип из фабрики по пространству имен и имени типа
ТипОбъекта = ФабрикаXDTO.Тип("http://www.example.com/integration", "MyResponseTypeName");

Попытка
    // Читаем XML, указывая ожидаемый тип для строгой проверки
    ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ТипОбъекта);
    
    // Перебор вложенных данных
    Для каждого СтрокаДанных Из ОбъектXDTO.return.rows Цикл
        Сообщить(СтрокаДанных.Name);
    КонецЦикла;
Исключение
    Сообщить("Ошибка чтения: " + ОписаниеОшибки());
КонецПопытки;

Важно помнить: если вы используете метод ПрочитатьXML без указания типа вторым параметром, 1С попытается определить тип автоматически по корневому элементу XML. Если в схеме этот элемент не помечен как Корневое свойство, возникнет ошибка.

Устранение проблем при записи XML: борьба с дублированием тегов

Рассмотрим распространенную ошибку, когда при формировании файла теги начинают дублироваться, например, вместо <Data>1</Data> получается <Data><Data>1</Data></Data>. Проанализируем типичный ошибочный код:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
ЗаписьXML.ЗаписатьНачалоЭлемента("GetInform"); // ОШИБКА: ручное создание тега

// Фабрика сама умеет записывать имя элемента
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектGetInform, "GetInform"); 

ЗаписьXML.ЗаписатьКонецЭлемента();

Почему это происходит? Метод ЗаписатьXML третьим параметром принимает ЛокальноеИмя. Если вы уже открыли элемент вручную через ЗаписатьНачалоЭлемента, а затем вызвали метод фабрики с тем же именем, 1С создаст вложенную структуру. Чтобы этого избежать, используйте один из двух подходов:

  1. Либо доверьте создание корневого тега полностью фабрике, не открывая его вручную.
  2. Либо, если вы записываете объект XDTO внутрь уже существующей сложной структуры, не указывайте имя элемента в методе ЗаписатьXML, если объект должен "слиться" с текущим уровнем.

Работа с внешними XSD-схемами и импортом

Иногда сторонние разработчики предоставляют схемы с ошибками или отсутствующими параметрами. Разберем ситуацию с targetNamespace. Если в импортируемой схеме не указано пространство имен, 1С может выдать ошибку при загрузке пакета. Это так называемые "хамелеонные" схемы.

Проанализируем способы решения этой задачи:


НаборСхем = Новый НаборСхемXML;
НаборСхем.Добавить("C:\Schemas\BaseTypes.xsd");
НаборСхем.Добавить("C:\Schemas\MainService.xsd");

// Создаем фабрику, объединяющую несколько файлов схем
МояФабрика = Новый ФабрикаXDTO(НаборСхем);

Советы по отладке XDTO

Если объект не читается, попробуйте воспользоваться методом Проверить(). После того как вы получили ОбъектXDTO (возможно, через чтение без привязки к типу или путем ручного заполнения), вызовите этот метод. Платформа укажет на конкретное свойство, которое нарушает правила схемы.

Также стоит обратить внимание на свойство "Смешанное" (Mixed) в определении типа в пакете XDTO. Если ваш XML содержит текст между дочерними тегами, а в схеме это не разрешено, 1С выдаст ошибку валидации. Установка этого флага позволяет игнорировать лишние пробелы и текстовые узлы внутри сложных типов.

Посмотрим на ситуацию со стороны HTML-тегов еще раз. Если в процессе отладки вы видите, что ошибка происходит на символе <, обязательно проверьте содержимое переменной ЧтениеXML. С большой вероятностью вместо данных там находится текст ошибки веб-сервера. Используйте метод ЧтениеXML.Контекст() или просто сохраните поток в текстовый файл для визуального анализа перед вызовом фабрики.

← На главную