Как прочитать XSD-схему в 1С, если в ней не указано пространство имен (targetNamespace)

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

При интеграции 1С с государственными информационными системами, такими как ГИС МТ «Честный ЗНАК», разработчики часто сталкиваются со специфическими XSD-схемами. Одной из распространенных проблем является отсутствие в файле схемы атрибута targetNamespace. Это ставит в тупик при попытке создать фабрику XDTO, так как непонятно, к какому пространству имен обращаться для создания объектов. Рассмотрим подробно, как решить эту задачу, правильно загрузить зависимые файлы и начать работу с данными маркировки.

Разбор проблемы: почему фабрика не видит типы

Когда мы используем метод СоздатьФабрикуXDTO(ИмяФайла), платформа анализирует структуру XSD. Если в корневом элементе <xs:schema> не определен целевой URI (атрибут targetNamespace), 1С помещает все определенные в файле типы в так называемое «пустое» пространство имен. Попытка получить тип через Фабрика.Тип("http://www.w3.org/2001/XMLSchema", "acceptance") или через неопределенное пространство приведет к ошибке, так как 1С ожидает точного соответствия URI.

Ситуация осложняется наличием директивы <xs:include>. В схемах «Честного ЗНАКА» часто используется разделение: основной документ (например, приемка) описывается в одном файле, а базовые типы (ИНН, GUID, сроки) — в другом, например, LP_base_types_v2.xsd. Если загрузить только основной файл, фабрика не сможет разрешить ссылки на базовые типы.

Решение 1: Работа с «пустым» пространством имен

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

Во-первых, если файлов несколько, их необходимо загружать массивом. Это позволит 1С сопоставить include внутри файлов. Посмотрим на пример кода:


СписокФайлов = Новый Массив;
СписокФайлов.Добавить("C:\Schemas\acceptance.xsd");
СписокФайлов.Добавить("C:\Schemas\LP_base_types_v2.xsd");

Попытка
    МояФабрика = СоздатьФабрикуXDTO(СписокФайлов);
Исключение
    Сообщить("Ошибка создания фабрики: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Во-вторых, после создания фабрики, для получения типа acceptance, мы должны использовать пустую строку. Выясним, как это выглядит в коде:


// Правильное получение типа из схемы без targetNamespace
ТипПриемка = МояФабрика.Тип("", "acceptance");

// Создание объекта XDTO
ОбъектПриемка = МояФабрика.Создать(ТипПриемка);

Важный момент: если вы укажете Неопределено вместо "", система может не найти тип, так как для XDTO пустая строка и отсутствие значения — не всегда одно и то же при поиске в пространстве имен.

Решение 2: Программная модификация XSD (Добавление Namespace)

Иногда для удобства разработки или из-за особенностей интеграции с другими системами удобнее, чтобы пространство имен все же было явно задано. Рассмотрим вариант, когда мы принудительно внедряем URI в схему перед ее чтением. Это можно сделать прямо в памяти, не изменяя исходные файлы на диске.

Выполним следующие действия: прочитаем текст файла, найдем тег <xs:schema> и добавим в него атрибут targetNamespace и соответствующий xmlns. Проанализируем пример функции:


Функция ПодготовитьСхемуСПространствомИмен(ПутьКФайлу, НужныйURI)
    ЧтениеТекста = Новый ЧтениеТекста(ПутьКФайлу);
    ТекстСхемы = ЧтениеТекста.Прочитать();
    ЧтениеТекста.Закрыть();
    
    // Заменяем начало тега, добавляя наше пространство имен
    ТекстСхемы = СтрЗаменить(ТекстСхемы, 
        "<xs:schema", 
        "<xs:schema targetNamespace=""" + НужныйURI + """ xmlns=""" + НужныйURI + """");
        
    Возврат ТекстСхемы;
КонецФункции

Однако помните: если вы добавили targetNamespace в основной файл, вы обязаны добавить его и во все файлы, которые подключаются через include. В противном случае механизм include сломается, так как он требует совпадения пространств имен включаемого и включающего файлов. В такой ситуации лучше использовать директиву import, но это потребует более сложной переработки XSD.

Использование СхемаXML для отладки структуры

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


Схема = Новый СхемаXML;
Схема.ПерейтиКСодержимому(ИмяФайла);

Для Каждого ЭлементСхемы Из Схема.Элементы Цикл
    Сообщить("Найден элемент: " + ЭлементСхемы.Имя + " [URI: " + ЭлементСхемы.ПространствоИмен + "]");
КонецЦикла;

Для Каждого ТипСхемы Из Схема.Типы Цикл
    Сообщить("Доступен тип: " + ТипСхемы.Имя);
КонецЦикла;

Этот метод позволяет точно выяснить, под каким URI «прописались» типы в памяти 1С. Если в поле ПространствоИмен вы видите пустую строку — значит, гипотеза о пустом пространстве имен верна.

Особенности работы с документами ГИС МТ (Честный ЗНАК)

При работе с XDTO для маркировки недостаточно просто прочитать схему. Рассмотрим несколько критических нюансов, которые помогут избежать ошибок при отправке данных на сервер ЦРПТ:

  1. Строгий порядок полей: В схемах используется конструкция <xs:sequence>. Это означает, что элементы в XML должны идти строго в том порядке, в котором они описаны в XSD. При использовании объекта XDTO 1С следит за этим сама, но если вы заполняете объект программно, старайтесь добавлять свойства последовательно.
  2. Фиксированные атрибуты: В примере из темы мы видим <xs:attribute name="version" fixed="5"/>. При создании объекта через Фабрика.Создать() это значение может не установиться автоматически. Всегда проверяйте наличие таких атрибутов и устанавливайте их вручную: ОбъектПриемка.version = 5;.
  3. Типы данных: Обратите внимание на типы вроде inn_type или datetimeoffset_type. Они определены во внешнем файле LP_base_types_v2.xsd. Если вы не загрузите этот файл в массиве при создании фабрики, 1С выдаст ошибку "Тип не определен" при попытке прочитать основной файл.

Итоговый алгоритм загрузки

Проанализируем финальную последовательность действий для успешного входа в разработку под маркировку:

Соблюдение этих правил позволит вам быстро "вкатиться" в работу с маркировкой и избежать типичных ошибок при работе со сложными XSD-схемами без явно заданных пространств имен.

← На главную