Как получить текстовые значения элементов XML при чтении в ОбъектXDTO через Последовательность

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

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

Разберем причину возникновения проблемы: Смешанное содержимое (Mixed Content)

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

Проанализируем ситуацию: когда мы используем метод ФабрикаXDTO.ПрочитатьXML() без жестко заданной схемы (XSD), 1С строит тип объекта «на лету». Если внутри тега, например <param>, находится текст, платформа помещает его в специальный системный механизм — ПоследовательностьXDTO (Sequence). Именно поэтому прямое обращение к ОбъектXDTO.param возвращает ссылку на объект или список, но не само текстовое значение.

Решение 1: Использование метода ПолучитьТекст() и объекта Последовательность

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

Рассмотрим пример кода, который позволяет получить текст из первого элемента списка:


// Предположим, ОбъектXDTO уже прочитан из ЧтениеXML
Если ОбъектXDTO.Свойства().Получить("param") <> Неопределено Тогда
    // Обращаемся к последовательности конкретного элемента
    ЗначениеТекста = ОбъектXDTO.param[0].Последовательность().ПолучитьТекст(0);
    Сообщить(ЗначениеТекста);
КонецЕсли;

Важно помнить, что метод ПолучитьТекст() принимает индекс текстового блока. Если текст внутри тега разбит другими тегами или комментариями, текстовых блоков может быть несколько. Метод ПолучитьТекст(0) вернет только первый фрагмент.

Решение 2: Универсальный обход последовательности в цикле

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

Посмотрим на пример реализации такого обхода:


ТекстРезультат = "";
Последовательность = ОбъектXDTO.Последовательность();

Для Индекс = 0 По Последовательность.Количество() - 1 Цикл
    // Проверяем, является ли текущий элемент последовательности текстом
    // Текстовые узлы в последовательности не имеют метаданных свойства
    Если Последовательность.ПолучитьСвойство(Индекс) = Неопределено Тогда
        ТекстРезультат = ТекстРезультат + Последовательность.ПолучитьТекст(Индекс);
    КонецЕсли;
КонецЦикла;

Сообщить("Полный текст узла: " + ТекстРезультат);

Этот подход особенно полезен при разборе сложных форматов, таких как YML (Yandex Market Language) или выгрузки из интернет-магазинов, где описания товаров могут содержать как текст, так и HTML-подобную разметку внутри одного тега.

Решение 3: Настройка параметров чтения XML

Иногда поведение ЧтениеXML влияет на то, как XDTO интерпретирует данные. При установке параметров чтения можно указать, как обрабатывать пробельные символы и CDATA. Выясним, как правильно инициализировать чтение, чтобы минимизировать потерю данных:


ЧтениеXML = Новый ЧтениеXML;
// Параметры: ... Игнорировать пробелы = Истина, Расширять префиксы = Истина
ПараметрыЧтенияХМЛ = Новый ПараметрыЧтенияXML(,,,,,,,,Истина, Истина);
ЧтениеXML.УстановитьСтроку(ТекущаяСтрока, ПараметрыЧтенияХМЛ);

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

Использование флага ИгнорироватьПробелы помогает избавиться от лишних «пустых» текстовых узлов в последовательности, оставляя только значимую информацию.

Альтернативный подход: Использование Построителя DOM

Если работа с ПоследовательностьXDTO кажется слишком громоздкой или методы 1С ведут себя непредсказуемо, можно рассмотреть вариант с использованием ПостроительDOM. Хотя в обсуждении упоминалось, что это более трудоемкий процесс, он дает полный контроль над структурой документа.

Проанализируем, как это работает:

  1. Создаем объект ЧтениеXML и загружаем в него данные.
  2. Используем ПостроительDOM для получения ДокументDOM.
  3. Находим нужные узлы по имени тега.
  4. Обращаемся к свойству ТекстовоеСодержимое (TextContent) узла.

Пример кода через DOM:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекущаяСтрока);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);

СписокУзлов = ДокументDOM.ПолучитьЭлементыПоИмени("param");
Для Каждого Узел Из СписокУзлов Цикл
    // Свойство ТекстовоеСодержимое соберет весь текст внутри тега автоматически
    Значение = Узел.ТекстовоеСодержимое;
    Сообщить(Значение);
КонецЦикла;

Сравнение методов: XDTO против DOM

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

DOM является «стандартом де-факто» для работы с произвольными XML-документами. Главное преимущество здесь — свойство ТекстовоеСодержимое, которое избавляет от необходимости вручную склеивать фрагменты из последовательности. Однако DOM потребляет больше оперативной памяти, так как загружает всё дерево документа целиком.

Подводя итог, если вы столкнулись с «пустыми» значениями в ОбъектXDTO, первым делом проверьте наличие свойства Последовательность. В 90% случаев данные находятся именно там, скрытые механизмом обработки смешанного содержимого платформы 1С.

← На главную