Механизм XDTO (XML Data Transfer Objects) в 1С является мощным инструментом для работы с XML-документами в объектном стиле. Он позволяет нам описывать структуру данных и манипулировать ими, не углубляясь в низкоуровневые детали XML, такие как теги и атрибуты. Часто возникает потребность добавить к существующему XDTO-объекту собственное, пользовательское свойство, например, для передачи дополнительных характеристик товара при обмене данными. Давайте вместе разберемся, как это сделать, рассмотрим различные сценарии и подводные камни.
Прежде чем приступать к модификации, нам важно понять, как устроен механизм XDTO. В его основе лежит ФабрикаXDTO – глобальный объект, который содержит описание всех типов данных и их взаимосвязей. Мы работаем с XDTO-пакетами, которые объединяют связанные типы. Каждый тип может описывать либо простой тип (например, строка, число), либо сложный объект, состоящий из других свойств. Для освоения базовых принципов работы с этой технологией с самого начала можно использовать руководство по основам работы с механизмом XDTO.
В нашем случае, как мы видим из кода, мы имеем дело с объектом ПакетПредложенийXDTO, который, вероятно, является частью пакета CML (CommerceML). Нам необходимо добавить к нему новое свойство, например, "ХарактеристикиТовара".
Функция ПакетCML()
URIПространстваИмен = ОбменССайтомПовтИсп.ПространствоИменСхемы;
Возврат ФабрикаXDTO.Пакеты.Получить(URIПространстваИмен);
КонецФункции
Функция ВыгрузитьПакетПредложений()
ПакетCML = ПакетCML();
ПакетПредложенийXDTO = ФабрикаXDTO.Создать(ПакетCML.Получить("ПакетПредложений"));
// Здесь нам нужно добавить ХарактеристикиТовара к ПакетПредложенийXDTO
КонецФункции
Основная сложность, с которой мы можем столкнуться, — это незнание того, где находится и как модифицировать соответствующий XDTO-пакет. Давайте начнем с поиска.
Перед тем как добавить свойство, нам необходимо найти сам XDTO-пакет, который описывает структуру нашего объекта. Это может оказаться не всегда очевидной задачей. Рассмотрим несколько способов поиска.
Поиск по URI пространства имен.
Как мы видим из предоставленного кода, URI пространства имен для схемы используется для получения пакета: URIПространстваИмен = ОбменССайтомПовтИсп.ПространствоИменСхемы; Возврат "urn:1C.ru:commerceml_2";. Это наш основной ключ для поиска.
Мы можем использовать глобальный поиск в конфигураторе (обычно Ctrl+Shift+F или Ctrl+F) и ввести строку поиска "urn:1C.ru:commerceml_2". Этот поиск покажет все места в конфигурации, где упоминается данный URI. Часто это приводит нас либо к прямому XDTO-пакету в дереве метаданных, либо к макету, где хранится соответствующая XSD-схема.
Функция ПространствоИменСхемы Экспорт
Возврат "urn:1C.ru:commerceml_2";
КонецФункции
Просмотр ветки "Общие" -> "XDTO-пакеты".
Если XDTO-пакет является частью конфигурации как отдельный объект метаданных, мы найдем его в дереве метаданных в ветке "Общие" -> "XDTO-пакеты". Просмотрите список пакетов – возможно, там окажется пакет с именем, соответствующим CommerceML или содержащий указанный URI.
Пакеты, хранящиеся в макетах.
Это более сложный, но весьма распространенный сценарий, особенно в типовых конфигурациях. Схема XDTO (или XSD-файл, из которого она загружается) может храниться в одном из макетов конфигурации. Если глобальный поиск по URI не привел нас к XDTO-пакету в ветке "Общие", но показал ссылку на какую-либо процедуру или функцию, которая возвращает эту схему, то, вероятно, она находится в макете.
Предположим, наш ОбменССайтомПовтИсп.ПространствоИменСхемы указывает на макет, содержащий XML-схему (XSD-файл). Для работы с такой схемой нам понадобится выполнить следующие шаги:
.xsd (например, cml2.xsd).Важно: Этот подход часто требует большей осторожности, так как модификация макета может быть равносильна изменению конфигурации и потребовать обновления на всех сторонах обмена.
Как только мы нашли XDTO-пакет, который необходимо модифицировать, мы можем применить один из следующих методов для добавления нового свойства. Выбор метода зависит от того, где находится пакет (встроенный или внешний/из макета) и насколько глубокие изменения мы готовы вносить в конфигурацию.
Этот метод является наиболее простым и предпочтительным, если наш XDTO-пакет находится непосредственно в ветке "Общие" -> "XDTO-пакеты" конфигурации. Он позволяет нам использовать встроенный редактор 1С, который упрощает процесс.
Общие" -> "XDTO-пакеты".urn:1C.ru:commerceml_2" или имеет соответствующее название, например, "CommerceML_2_07".ПакетПредложений". Разворачиваем узлы до тех пор, пока не найдем его.ПакетПредложений"). Затем нажимаем кнопку "Добавить свойство" (обычно она находится на панели инструментов окна редактирования XDTO-пакета) или используем пункт контекстного меню "Добавить" -> "Свойство".ХарактеристикиТовара".Строка, Число, Дата, Булево), так и более сложный, ранее определенный XDTO-тип, если вы планируете передавать структурированные данные. Для характеристик часто подходит Строка.0..1 (необязательное, одно значение)1..1 (обязательное, одно значение)0..* (необязательное, список значений)1..* (обязательное, список значений)Порядок, Отображение и т.д., настраиваем по необходимости.Обновить конфигурацию базы данных" или клавиша F7). Без этого изменения не вступят в силу.Важный момент: Этот метод предполагает прямое изменение конфигурации. В типовых решениях это может повлиять на поддержку, так как мы модифицируем стандартный объект. Если вы работаете с расширением конфигурации, убедитесь, что вы либо используете расширение для XDTO-пакета, либо применяете метод с внешним XSD, если прямой модификации в расширении недостаточно.
Этот метод применяется, когда XDTO-пакет не является встроенным объектом конфигурации (например, он загружается из внешнего XSD-файла или хранится в макете как XML-текст) или когда мы хотим избежать прямого изменения конфигурации. Он дает большую гибкость, но требует знания синтаксиса XSD.
.xsd (например, cml2_modified.xsd), как мы обсуждали в разделе поиска.<xs:complexType name="ПакетПредложений"> или аналогичное определение для объекта, который содержит список предложений.<xs:complexType> мы добавляем новое свойство как элемент (<xs:element>) или атрибут (<xs:attribute>), в зависимости от наших потребностей и структуры схемы. Как правило, характеристики добавляют как элементы.
<xs:complexType name="ПакетПредложений">
<xs:sequence>
<!-- Существующие элементы пакета предложений -->
<xs:element name="Ид" type="xs:string" minOccurs="0"/>
<xs:element name="Наименование" type="xs:string" minOccurs="0"/>
<!-- Наше новое свойство -->
<xs:element name="ХарактеристикиТовара" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
Здесь minOccurs="0" означает, что элемент необязательный, а type="xs:string" – что это строковый тип.
targetNamespace (целевое пространство имен) корректно определено в вашей XSD-схеме и что все ссылки на типы внутри схемы верны. Некорректный синтаксис XSD приведет к ошибкам при загрузке.Теперь, когда у нас есть модифицированный XSD-файл, мы можем использовать его в нашем коде 1С для создания новой фабрики XDTO. Эта фабрика будет "знать" о нашем новом свойстве. Мы будем пользоваться этой новой фабрикой вместо глобальной ФабрикаXDTO для создания объектов, если хотим использовать наше новое свойство. При необходимости можно воспользоваться готовым примером динамического создания ФабрикиXDTO на лету для программной реализации этого процесса.
// Определяем полный путь к нашему модифицированному XSD-файлу
ПолныйПутьКФайлуСхемы = "C:\МоиСхемы\cml2_modified.xsd";
// Создаем массив с путями к XSD-файлам
// Если у вас несколько схем, которые ссылаются друг на друга,
// их все нужно добавить в этот массив
ФайлыXSD = Новый Массив;
ФайлыXSD.Добавить(ПолныйПутьКФайлуСхемы);
// Создаем новую фабрику XDTO на основе наших схем
// Эту фабрику мы будем использовать для создания объектов,
// которые должны содержать наше новое свойство.
МояФабрикаXDTO = СоздатьФабрикуXDTO(ФайлыXSD);
// Теперь мы можем использовать МояФабрикаXDTO для получения пакетов
// и создания объектов с учетом наших новых свойств
URIПространстваИмен = "urn:1C.ru:commerceml_2"; // Убедитесь, что это URI из вашего XSD
ПакетCML = МояФабрикаXDTO.Пакеты.Получить(URIПространстваИмен);
ТипОбъекта = ПакетCML.Получить("ПакетПредложений");
// Создаем объект XDTO, используя нашу новую фабрику
ПакетПредложенийXDTO = МояФабрикаXDTO.Создать(ТипОбъекта);
// Теперь у объекта ПакетПредложенийXDTO будет свойство ХарактеристикиТовара
// Мы можем присвоить ему значение
ПакетПредложенийXDTO.ХарактеристикиТовара = "Цвет: красный, Размер: L, Материал: хлопок";
// Далее мы можем сериализовать этот объект в XML
// или передать его для дальнейшей обработки
Сериализатор = МояФабрикаXDTO.СоздатьСериализатор();
СтрокаXML = Сериализатор.ЗаписатьВСтроку(ПакетПредложенийXDTO, URIПространстваИмен);
Сообщить(СтрокаXML);
Этот подход позволяет нам работать с модифицированной схемой, не меняя глобальную ФабрикаXDTO и, соответственно, не влияя на стандартные механизмы обмена, если они используют исходную, немодифицированную схему.
Для типовых конфигураций, особенно при работе с механизмами обмена, такими как EnterpriseData, фирма "1С" предоставляет специальный механизм расширения XDTO-пакетов. Начиная с определенных версий платформы, это позволяет добавлять новые свойства без снятия конфигурации с поддержки, что является очень ценным преимуществом. Для реализации более масштабных проектов перехода на новые конфигурации доступен раздел с решениями для переноса данных 1С по тарифу PRO.
Ключевое правило этого механизма заключается в том, что мы можем только расширять состав пакета (добавлять новые элементы или атрибуты), но не удалять или переименовывать существующие. Это обеспечивает обратную совместимость и минимизирует риски при обновлении.
Важно помнить: XSD-схема для расширения формата должна быть идентичной в обеих конфигурациях 1С, участвующих в обмене (например, конфигурации-отправителе и конфигурации-получателе). Это включает не только состав добавленных элементов, но и их порядок. Несоответствие схем может привести к ошибкам парсинга или некорректной передаче данных. Если правила обмена настроены, саму процедуру передачи можно автоматизировать через программу для регулярной синхронизации данных между базами 1С.
Мы используем этот механизм, когда нам нужно добавить дополнительные синхронизируемые поля к стандартным объектам обмена, не затрагивая ядро типового решения. Проверить результат передачи сведений после модификации обмена поможет автоматическое сравнение бухгалтерских проводок между базами 1С.
При работе с XDTO важно учитывать некоторые особенности и потенциальные ограничения:
Обращение к данным как к объектам 1С. Одним из главных преимуществ XDTO является возможность обращаться к элементам XML-файла как к свойствам объектов 1С, используя "точечную" нотацию (например, ОбъектXDTO.Свойство). Это значительно упрощает чтение и запись XML-данных.
Строгая проверка типов. XDTO строго следит за соответствием типов данных. При попытке добавить свойство, которого нет в схеме, или присвоить значение неверного типа, вы получите ошибку выполнения. Это обеспечивает целостность данных, но требует внимательности при разработке.
Пространства имен (URI). Пространства имен пакетов XDTO критически важны для обеспечения уникальности типов и должны быть уникальными в пределах конфигурации. Убедитесь, что ваше targetNamespace корректно определено в XSD-схеме, особенно если вы работаете с внешними файлами.
Сериализация и десериализация. Для преобразования объектов XDTO в XML-строку (сериализация) и обратно (десериализация) используется специальный сериализатор XDTO. Он позволяет нам легко обмениваться данными с другими системами.
Предопределенные типы. ФабрикаXDTO автоматически регистрирует предопределенные типы значений, совпадающие с примитивными типами XML Schema (например, string, int, date, boolean). Это позволяет нам использовать их без дополнительного описания.
Внешние пакеты. Если XDTO-пакет является внешним (то есть его нет в конфигурации, и вы получили его от другой системы), возможности его модификации могут быть ограничены. В таких случаях часто требуется обращение к разработчикам оригинального ПО или использование метода создания новой ФабрикиXDTO с модифицированной локальной копией XSD-схемы.
Мы выяснили, что добавление пользовательского свойства к XDTO-объекту в 1С – это решаемая задача, к которой можно подойти различными способами. Независимо от того, является ли XDTO-пакет встроенным в конфигурацию или находится во внешнем XSD-файле/макете, существуют четкие шаги для его модификации. Важно всегда помнить о необходимости тестирования изменений, особенно при обмене данными с другими системами, чтобы обеспечить их корректную работу с новой структурой. Выбор метода зависит от вашей конкретной ситуации, уровня контроля над конфигурацией и потребностей в гибкости.