К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: как прочитать объект XDTO

Как прочитать объект XDTO в 1С: чтение XML через ЧтениеXML и ФабрикаXDTO, обход свойств, проверка типов, обработка ошибок и типовые примеры кода.

Объект XDTO в 1С — это представление XML-документа в виде дерева объектов, с которым можно работать как с обычными структурами данных: обращаться к свойствам, перебирать списки, проверять типы. Технология XDTO (XML Data Transfer Objects) лежит в основе обмена данными с веб-сервисами, загрузки выписок, интеграции по форматам EnterpriseData и CommerceML, а также работы с любыми XML-файлами, для которых известна схема.

«Прочитать объект XDTO» на практике означает одну из двух задач: либо загрузить XML-файл или строку в объект XDTO через фабрику, либо обойти уже существующий объект XDTO и извлечь из него значения. Обе задачи решаются штатными средствами платформы без сторонних компонент.

Ниже разобраны оба сценария с рабочим кодом, способы проверки типов и свойств, обработка списков и ошибок, а также критерии выбора между XDTO и последовательным чтением XML.

Что такое объект XDTO и когда его читают

XDTO — механизм платформы 1С, который сопоставляет XML-документу объектную модель на основе схемы (XSD). Фабрика XDTO знает, какие элементы и атрибуты допустимы, какого они типа и какие из них обязательны. Благодаря этому разработчик работает не с текстом XML, а с типизированными объектами: строками, числами, датами, вложенными объектами и списками.

Объект XDTO приходится читать в типовых сценариях: загрузка ответа веб-сервиса, импорт файла обмена (например, CommerceML от сайта или EnterpriseData из другой информационной базы), разбор XML, полученного от банка или оператора ЭДО, чтение настроек и пакетов обмена. Во всех случаях исходные данные — это XML-документ, а результат — дерево объектов XDTO.

Чтение XML в объект XDTO через ФабрикаXDTO

Базовая последовательность: создать объект ЧтениеXML, открыть файл или установить строку, затем вызвать ФабрикаXDTO.ПрочитатьXML(). Метод вернёт значение типа ОбъектXDTO — корневой элемент документа с учётом его схемы.

Пример чтения из файла:

ЧтениеXML = Новый ЧтениеXML;

ЧтениеXML.ОткрытьФайл("C:\Обмен\order.xml");

ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);

ЧтениеXML.Закрыть();

Сообщить(ОбъектXDTO.Тип().Имя); // имя корневого типа

Если XML находится в строке (например, тело ответа HTTP-запроса), вместо ОткрытьФайл используется УстановитьСтроку:

ЧтениеXML = Новый ЧтениеXML;

ЧтениеXML.УстановитьСтроку(ТелоОтвета);

ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);

ЧтениеXML.Закрыть();

bsl
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяФайла);
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();

Если корневой тип документа заранее известен, его можно передать вторым параметром: ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ТипXDTO). Это полезно, когда фабрика не может однозначно определить тип по пространству имён или требуется строгая проверка соответствия схеме.

Обращение к свойствам объекта XDTO

После чтения данные доступны как свойства объекта: ОбъектXDTO.Номер, ОбъектXDTO.Дата, ОбъектXDTO.Контрагент.Наименование. Имена свойств совпадают с именами элементов и атрибутов в схеме. Вложенные элементы образуют вложенные объекты XDTO, обращение к ним идёт через точку.

Главная ловушка — необязательные свойства. Если элемент отсутствует в XML, обращение к свойству вернёт Неопределено, а обращение к свойству несуществующего вложенного объекта вызовет ошибку. Поэтому перед чтением проверяйте заполненность:

Если ОбъектXDTO.Установлено("Контрагент") Тогда

Наименование = ОбъектXDTO.Контрагент.Наименование;

Иначе

Наименование = "";

КонецЕсли;

Метод Установлено() возвращает Истина, если свойство присутствует в документе. Альтернатива — сравнение значения свойства с Неопределено, но Установлено() надёжнее, поскольку явно отражает факт наличия элемента в XML.

Работа со списками и коллекциями XDTO

Элементы, которые в схеме могут повторяться (maxOccurs больше 1), фабрика возвращает как СписокXDTO. Его обходят циклом Для Каждого, а количество элементов узнают через Количество().

Для Каждого СтрокаТовара Из ОбъектXDTO.Товары.Товар Цикл

Сообщить(СтрокаТовара.Наименование + " — " + СтрокаТовара.Количество);

КонецЦикла;

Важная особенность: если повторяющийся элемент встретился в документе один раз, фабрика всё равно вернёт список — при условии, что тип известен по схеме. Но если тип определён неявно или схема не загружена, одиночный элемент может вернуться как объект, а не список. Универсальная защита — проверка типа значения:

Значение = ОбъектXDTO.Товар;

Если ТипЗнч(Значение) = Тип("СписокXDTO") Тогда

Для Каждого Элемент Из Значение Цикл

// обработка элемента списка

КонецЦикла;

ИначеЕсли Значение <> Неопределено Тогда

// обработка одиночного объекта

КонецЕсли;

Типичные ошибки
01
Обход списка без проверки типа: при единственном элементе цикл «Для Каждого» по объекту XDTO перебирает его свойства, а не строки данных
02
Обращение к необязательному свойству без Установлено() — исключение на файлах, где элемент отсутствует
03
Чтение всего файла в XDTO при огромном объёме: документ целиком загружается в память, на больших файлах возможна нехватка памяти
04
Игнорирование пространства имён: ПрочитатьXML с явным типом не находит тип, если пространство имён в файле отличается от ожидаемого

Проверка типов и диагностика структуры

При разборе незнакомого XML полезно сначала изучить полученное дерево. Метод ОбъектXDTO.Тип() возвращает ТипОбъектаXDTO с именем и пространством имён. Список свойств типа доступен через коллекцию Свойства, а собственные значения объекта — через метод Свойства() самого объекта.

Для Каждого Свойство Из ОбъектXDTO.Свойства() Цикл

Сообщить(Свойство.Имя + " : " + Свойство.Тип.Имя);

КонецЦикла;

Такой перебор помогает понять структуру документа без исходной схемы: какие элементы реально пришли, какие из них списки, какие — вложенные объекты. Это первый шаг при разборе ошибок вида «свойство не обнаружено».

Порядок чтения объекта XDTO
  1. 1
    Получите XML: файл, строка ответа сервиса или поток обмена
  2. 2
    Создайте ЧтениеXML и откройте источник (ОткрытьФайл или УстановитьСтроку)
  3. 3
    Вызовите ФабрикаXDTO.ПрочитатьXML(ЧтениеXML) и закройте чтение
  4. 4
    Проверьте тип корневого объекта через Тип() — убедитесь, что прочитан нужный документ
  5. 5
    Обходите свойства с проверкой Установлено(), списки — циклом с проверкой ТипЗнч
  6. 6
    Перенесите значения в объекты конфигурации и зафиксируйте результат

Обработка ошибок чтения

ПрочитатьXML генерирует исключение, если XML некорректен синтаксически или нарушает схему (не тот тип элемента, отсутствует обязательный атрибут). Чтение всегда стоит оборачивать в попытку с информативной обработкой ошибки:

Попытка

ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);

Исключение

Сообщить("Ошибка чтения XML: " + ОписаниеОшибки());

ЧтениеXML.Закрыть();

Возврат;

КонецПопытки;

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

Когда XDTO не нужен: альтернативы

XDTO оправдан, когда есть схема данных и нужна типизация: обмены по стандартным форматам, веб-сервисы, пакеты EnterpriseData. Если XML простой и разбирается один раз, проще использовать последовательное чтение через ЧтениеXML с проверкой ТипУзла — код длиннее, но не требует пакетов XDTO и экономит память.

Для произвольного XML без схемы есть ещё вариант — ФабрикаXDTO.ПрочитатьXML с нестрогой моделью: фабрика построит объекты по фактической структуре документа. Свойства будут доступны по именам элементов, но без контроля типов. Это компромисс между удобством и строгостью.

Способы разбора XML в 1С

ФабрикаXDTO.ПрочитатьXML

Типизированные объекты по схеме; подходит для обменов и веб-сервисов. Ограничение: весь документ в памяти, нужна схема или нестрогий режим

Последовательное ЧтениеXML

Потоковый разбор узел за узлом; минимальный расход памяти. Ограничение: больше ручного кода, нет типизации

ЧтениеXML + ПрочитатьXML по фрагментам

Позиционирование на повторяющихся элементах и чтение каждого в XDTO; масштабируется на большие файлы, но сложнее в реализации

Контрольные точки

Как проверить результат чтения

Тип корневого объекта
Норма

Тип().Имя совпадает с ожидаемым корневым элементом схемы

Тревожный признак

Тип не определён или не совпадает — проверьте пространство имён и пакеты XDTO

Обязательные свойства
Норма

Установлено() возвращает Истина для всех ключевых полей

Тревожный признак

Свойства Неопределено — элемент отсутствует в файле или имя отличается

Списки
Норма

ТипЗнч(Свойство) = СписокXDTO, Количество() соответствует данным файла

Тревожный признак

Пришёл одиночный объект вместо списка — добавьте проверку типа

FAQ

Чем отличается ОбъектXDTO от ЗначениеXDTO?

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

Почему ПрочитатьXML выдаёт ошибку «Ошибка разбора XML»?

Чаще всего XML синтаксически некорректен: незакрытый тег, недопустимый символ, неверная кодировка. Откройте файл в текстовом редакторе и проверьте позицию, указанную в тексте ошибки. Также убедитесь, что строка не содержит BOM-маркеров или служебных заголовков перед декларацией XML.

Как прочитать XML, для которого в конфигурации нет пакета XDTO?

Вызовите ФабрикаXDTO.ПрочитатьXML без указания типа — фабрика построит объекты по фактической структуре документа. Свойства будут доступны по именам элементов, но типы значений будут строковыми, и контроль схемы не выполняется.

Как узнать, какие свойства есть у прочитанного объекта?

Переберите коллекцию ОбъектXDTO.Свойства() — она вернёт свойства, реально присутствующие в документе. Для полного списка допустимых свойств обратитесь к ОбъектXDTO.Тип().Свойства — это свойства, описанные в схеме типа.

Можно ли читать только часть большого XML через XDTO?

Да. Создайте ЧтениеXML, последовательно перемещайтесь методом Прочитать() до нужного элемента, затем вызовите ФабрикаXDTO.ПрочитатьXML(ЧтениеXML) — будет прочитан текущий элемент со всеми вложенными. Так обрабатывают большие файлы порциями без загрузки всего документа в память.

Почему цикл «Для Каждого» по свойству перебирает не строки, а поля?

Свойство оказалось одиночным ОбъектомXDTO, а не СпискомXDTO — так бывает, когда тип не задан схемой и элемент встретился один раз. Проверяйте ТипЗнч(Значение) перед циклом и обрабатывайте оба варианта.

Итог

Что важно запомнить

Объект XDTO читается через ФабрикаXDTO.ПрочитатьXML с предварительно открытым ЧтениеXML. Перед обращением к свойствам проверяйте Установлено(), списки — через ТипЗнч, а чтение оборачивайте в попытку. Для больших файлов используйте фрагментное чтение, для простых — последовательное ЧтениеXML.