Как получить текстовое значение элемента XML с атрибутами при чтении через XDTO в 1С?

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

При работе с интеграциями и обмене данными программисты 1С часто сталкиваются с необходимостью разбора XML-файлов. Одним из самых мощных и быстрых инструментов для этого является Фабрика XDTO. Однако стандартные методы обращения к свойствам объекта XDTO могут поставить в тупик, когда структура XML-узла содержит одновременно и атрибуты, и текстовое значение. В этой статье мы подробно разберем, почему возникает такая сложность и какими способами можно извлечь заветные данные.

Суть проблемы: когда «простое» становится «сложным»

Рассмотрим ситуацию. У нас есть стандартный элемент XML, который содержит только значение:

<csdo:ProductId>101803492600519</csdo:ProductId>

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


<casdo:CleanNetMassMeasure measurementUnitCode="166" measurementUnitCodeListId="2016">0.192</casdo:CleanNetMassMeasure>

В данном случае элемент CleanNetMassMeasure технически становится Complex Type с Simple Content (сложным типом с простым содержимым). Платформа 1С считывает атрибуты measurementUnitCode и measurementUnitCodeListId как свойства объекта XDTO, но само текстовое значение "0.192" оказывается скрыто внутри структуры объекта, так как оно не привязано ни к одному именованному свойству.

Решение 1: Использование механизмов последовательности XDTO

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

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


// Извлекаем текстовое значение из первого узла последовательности
ТекстовоеЗначение = СтрокаТоварыXDTO.Последовательность().ПолучитьТекст(0);

Важные нюансы этого метода:

  1. Индексация: Метод ПолучитьТекст(0) обращается к самому первому текстовому блоку внутри тега. В большинстве случаев (как в примере с массой) это именно то, что нужно.
  2. Риски форматирования: Если XML-файл был «красиво» отформатирован (содержал лишние переносы строк или пробелы внутри тега), первым элементом последовательности может оказаться символ переноса строки. В таких случаях стоит проверить содержимое или перебрать последовательность в цикле.
  3. Проверка типа: Чтобы сделать код более надежным, мы можем проанализировать состав последовательности целиком.

Решение 2: Доступ через системное свойство «Значение»

В некоторых случаях, в зависимости от настроек XDTO-пакета или версии платформы, 1С может автоматически сопоставить текстовое содержимое элемента со свойством Значение (или Value в англоязычной локализации). Прежде чем использовать работу с последовательностями, рекомендуется проверить наличие этого свойства:


Если СвойствоОбъектаXDTO(ОбъектXDTO, "Значение") Тогда
    НужныйТекст = ОбъектXDTO.Значение;
КонецЕсли;

Это более «чистый» способ обращения к данным, если структура XSD-схемы это подразумевает. Однако, если схема создается динамически «на лету» при чтении, этот вариант может не сработать.

Анализ типичных ошибок: Функция XMLЗначение

Рассмотрим ошибку, упомянутую в обсуждении. Часто разработчики пытаются использовать функцию XMLЗначение для преобразования типа, передавая в нее весь объект XDTO:


// ОШИБКА: Неверный второй параметр
Результат = XMLЗначение(Тип("Число"), СтрокаТоварыXDTO.CustomsValueAmount);

Проанализируем причину сбоя. Функция XMLЗначение ожидает на вход либо простую строку, либо объект типа ЧтениеXML. Когда мы передаем в нее ОбъектXDTO, содержащий в себе еще и атрибуты, функция не понимает, какую именно часть этого сложного объекта нужно преобразовывать в число. Правильный алгоритм действий должен быть таким:

  1. Сначала извлекаем текстовую строку с помощью Последовательность().ПолучитьТекст(0).
  2. Затем передаем полученную строку в функцию приведения типов.

Как правильно настроить XDTO-пакет в Конфигураторе

Если вы сами проектируете XDTO-пакет для импорта подобных файлов, вы можете избежать сложностей с последовательностями, правильно настроив структуру типа. Разберем по шагам, как это сделать:

  1. Создайте новый Тип объекта (Complex Type).
  2. В поле «Способ получения данных» (Content Type) установите значение Simple (Простой).
  3. В поле «Базовый тип» выберите подходящий простой тип (например, decimal из пространства имен http://www.w3.org/2001/XMLSchema).
  4. Добавьте в этот объект необходимые Атрибуты.

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

Альтернативный подход через прямое чтение

Если структура XML слишком непредсказуема или XDTO-пакет получается чрезмерно громоздким, мы можем комбинировать XDTO с классическим объектом ЧтениеXML. В момент, когда ЧтениеXML находится на нужном узле, мы можем извлечь данные следующим образом:


// Читаем атрибуты напрямую из потока
КодЕдиницы = ЧтениеXML.ПолучитьАтрибут("measurementUnitCode");

// Читаем только текстовое содержимое, пропуская вложенные элементы
ТекстовоеЗначение = ЧтениеXML.ПрочитатьСодержимое();

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

Резюмируем: при работе с XML через XDTO в 1С всегда помните, что любой элемент с атрибутами становится «объектом». Если вам нужно достать текст из такого объекта, вашим лучшим другом будет метод Последовательность().ПолучитьТекст(0) или правильная настройка Simple Content в схеме данных.

← На главную