====== XDTO ======
===== Что это такое =====
XDTO - это аббревиатура, обозначающая обмен данными посредством XML (XML Data Transfer Objects). Аббревиатура придумана разработчиками 1с и вряд ли встретится где-то ещё. Но реализует она вполне стандартизированный механизм обмена информацией с помощью файлов XML, известный как [[https://ru.wikipedia.org/wiki/XML_Schema|XML Schema]].
Суть этого механизма заключается в том, что создаётся специальный файл, называемый схемой. Этот файл описывает структуру XML-файла. Если XML-файл соответствует этой структуре, то он считается корректным. Отдающей стороне достаточно сформировать корректный XML-файл для успешного обмена. Принимающая сторона должна гарантировать, что любой корректный XML-файл будет загружен без ошибок. В результате достаточно легко можно обеспечить обмен между двумя и более закрытыми информационными системами. Каждая схема характеризуется пространством имён, которое должно быть уникальным. Оно связывает XML-файл со своей схемой.
Самым ярким примером использования такого механизма обмена являются различного рода декларации (налоговые и прочее). На сайтах соответствующих ведомств всегда можно найти файл со схемой. Другой распространённый пример - обмен данными с сайтом.
С точки зрения программиста 1с, объект XDTO очень похож на [[1c:коллекции:Фиксированная структура|Фиксированную структуру]], созданную на основе файла со схемой. Эта псевдоструктура может быть загружена из XML-файла и использована для загрузки сторонних данных. А может быть заполнена данными и записана в корректный XML-файл. Который впоследствии будет использован для загрузки в другую информационную систему. В любом случае работа с объектом состоит из 3 основных этапов: [[1c:общие:xdto#Получение типа объекта|получение типа объекта]], [[1c:общие:xdto#Создание объекта XDTO|создание объекта XDTO]] требуемого типа, использование объекта XDTO для [[1c:общие:xdto#Запись объектов XDTO в файл|выгрузки]] или [[1c:общие:xdto#Чтение объектов XDTO из файла|загрузки]] данных.
===== Получение типа объекта =====
Это наиболее трудный для понимания этап т.к. он не соответствует обычной работе с переменными 1с. Но для работы с объектами XDTO он обязателен. Прежде чем создать объект XDTO, необходимо получить его тип. Для этого используются специальные объекты - [[1c:глобальные_объекты:ФабрикаXDTO|фабрики типов XDTO]].
Платформа позволяет использовать 2 вида схем - встроенные в конфигурацию [[1c:объекты:XDTO-пакеты|XDTO-пакеты]] или внешние файлы с расширением .xsd и оформленные в соответствии со стандартами [[https://www.w3.org/TR/xmlschema-0/|w3c]]. Соответственно, существует 2 способа получения объекта-фабрики типов.
==== Использование XDTO-пакетов ====
[[1c:общие:ПакетыXDTO|XDTO-пакет]] - это отдельный объект конфигурации, расположенный в ветке Общие дерева конфигурации. Платформа позволяет создавать неограниченное количество XDTO-пакетов как с помощью конструктора, так и путём импорта существующих файлов .xsd. Эти пакеты могут служить основой для получения типов объектов XDTO. Выглядит это так:
ТипОбъектаНоменклатура = ФабрикаXDTO.Тип("http://www.wiki-1c.ru/xdto", "Номенклатура");
Здесь [[1c:общие:глобальные_объекты:ФабрикаXDTO]] - это особый глобальный объект, который знает всё обо всех объектах XDTO, описанных в имеющихся в конфигурации XDTO-пакетах. Метод [[1c:общие:глобальные_объекты:ФабрикаXDTO:Тип|Тип()]] возвращает искомый тип объекта XDTO ([[1c:объекты:ТипОбъектаXDTO]]). Он принимает 2 параметра - пространство имён и имя типа (оба - строки). Результат полезно запомнить в переменной, в дальнейшем её можно использовать для создания объектов XDTO произвольное количество раз.
Заметим, что в параметре передаётся не имя пакета, а его пространство имён. Имя пакета вообще нигде не используется и задаётся только для удобства поиска в дереве конфигурации.
==== Использование файлов с описанием схемы XML ====
Такие файлы традиционно имеют расширение .xsd. Преимущество данного метода в том, что он работает независимо от конфигурации. И если первому методу обязательно требуется отдельный объект конфигурации, этот требует только наличия файла со схемой. Вот код создания соответствующего объекта-фабрики и получение типа объекта XDTO:
МояФабрикаXDTO = СоздатьФабрикуXDTO("D:\Temp\goods.xsd");
ТипОбъектаНоменклатура = МояФабрикаXDTO.Тип("http://www.wiki-1c.ru/xdto", "Номенклатура");
Здесь мы использовали глобальную функцию [[1c:общие:глобальные_объекты:СоздатьФабрикуXDTO]], которая считывает файл со схемой (параметр функции) и создаёт объект-фабрику. Этот объект в будущем может произвольное число раз использоваться для создания любых доступных в схеме типов объектов. Если требуется загрузить несколько файлов со схемами, можно передать массив строк с именами файлов. Дальнейшая работа с фабрикой объектов не отличается от описанного в 1 способе.
===== Создание объекта XDTO =====
Сами объекты XDTO также создаются фабрикой объектов. Причём той же самой, которая использовалась при получении типа. Но используется уже другой метод - [[1c:общие:глобальные_объекты:ФабрикаXDTO:Создать|Создать()]]:
Номенклатура = МояФабрикаXDTO.Создать(ТипОбъектаНоменклатура);
В результате в переменной Номенклатура окажется объект XDTO, описанный в файле-схеме. К его реквизитам можно обращаться наподобие реквизитов фиксированной структуры. Естественно, нельзя добавлять или удалять реквизиты. В отличие от фиксированной структуры, каждый реквизит имеет определённый тип, поэтому произвольное присваивание не получится. Объект имеет тип [[1c:объекты:ОбъектXDTO]].
===== Запись объектов XDTO в файл =====
Прежде чем [[1c:общие:xdto#Запись объекта XDTO|записать объект]], его нужно заполнить. Принципы заполнения схожи с заполнением фиксированной структуры для реквизитов базовых типов, и с созданием объекта XDTO для прочих реквизитов.
==== Заполнение объекта XDTO ====
Использование фабрики объектов на этом не закончится. Ведь у переменной Номенклатура есть несколько реквизитов, и каждый из реквизитов относится к какому-то типу. К счастью, простые типы можно использовать без подобных преобразований простым присваиванием:
Номенклатура.Наименование = "Носки суровые";
Более сложные типы требуют обращения к фабрике объектов:
ТипОбъектаЕдиницаИзмерения = МояФабрикаXDTO.Тип("http://www.wiki-1c.ru/xdto", "ЕдиницаИзмерения");
ЕдиницаИзмерения = МояФабрикаXDTO.Создать(ТипОбъектаЕдиницаИзмерения);
ЕдиницаИзмерения.ОКЕИ = 796;
ЕдиницаИзмерения.Наименование = "шт";
Номенклатура.ЕдиницаИзмерения = ЕдиницаИзмерения;
Стандарт позволяет создавать реквизиты-списки и реквизиты-структуры без создания отдельных типов. Заполнять такие реквизиты можно следующим образом:
// Список элементов простых типов
Штрихкоды = Номенклатура.ПолучитьСписок("Штрихкоды");
Штрихкоды.Добавить("4601546124937");
Штрихкоды.Добавить("4601546093981");
// Список элементов сложных типов, описанных в схеме
ПрочиеЕдиницыИзмерения = Номенклатура.ПолучитьСписок("ПрочиеЕдиницыИзмерения");
ЕдиницаИзмерения = МояФабрикаXDTO.Создать(ТипОбъектаЕдиницаИзмерения);
ЕдиницаИзмерения.ОКЕИ = 166;
ЕдиницаИзмерения.Наименование = "кг";
ПрочиеЕдиницыИзмерения.Добавить(ЕдиницаИзмерения);
Здесь мы получаем объект-список методом [[1c:объекты:ОбъектXDTO:ПолучитьСписок|ПолучитьСписок()]] объекта XDTO. Объект-список имеет тип [[1c:объекты:СписокXDTO]].
Получение типа элементов-структур немного напоминает работу с метаданными конфигурации. Используем метод [[1c:объекты:ОбъектXDTO:Свойства|Свойства()]] для получения списка реквизитов ([[1c:объекты:КоллекцияСвойствXDTO]]). Далее получаем параметры реквизита методом списка [[1c:объекты:КоллекцияСвойствXDTO:Получить|Получить()]] ([[1c:объекты:СвойствоXDTO]]). В его реквизите [[1c:объекты:СвойствоXDTO:Тип]] и находится искомый тип значения.
// Список элементов-структур
Характеристики = Номенклатура.ПолучитьСписок("Характеристики");
ТипЭлементаХарактеристика = Номенклатура.Свойства().Получить("Характеристики").Тип;
Характеристика = МояФабрикаXDTO.Создать(ТипЭлементаХарактеристика);
Характеристика.Код = 1;
Характеристика.Наименование = "Жёлтые";
Характеристики.Добавить(Характеристика);
// Реквизиты-структуры
ТипОбъектаСчетаУчета = Номенклатура.Свойства().Получить("СчетаУчета").Тип;
Номенклатура.СчетаУчета = МояФабрикаXDTO.Создать(ТипОбъектаСчетаУчета);
Номенклатура.СчетаУчета.СчетУчетаОстатков = "10.01";
Номенклатура.СчетаУчета.СчетУчетаРасходов = "26";
Сейчас объект заполнен и его можно записать.
==== Запись объекта XDTO ====
Для записи воспользуемся объектом типа [[1c:объекты:ЗаписьXML]]. В него умеет писать фабрика объектов с помощью метода [[1c:общие:ФабрикаXDTO:ЗаписатьXML|ЗаписатьXML()]].
РезультатXML = Новый ЗаписьXML;
РезультатXML.УстановитьСтроку("UTF-8");
РезультатXML.ЗаписатьОбъявлениеXML();
МояФабрикаXDTO.ЗаписатьXML(РезультатXML, Номенклатура);
Результат = РезультатXML.Закрыть();
В результате в переменной ''Результат'' будет следующее содержимое:
<Номенклатура xmlns="http://www.wiki-1c.ru/xdto" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Наименование>Носки суровыеНаименование>
<ЕдиницаИзмерения>
<ОКЕИ>796ОКЕИ>
<Наименование>штНаименование>
ЕдиницаИзмерения>
<Штрихкоды>4601546124937Штрихкоды>
<Штрихкоды>4601546093981Штрихкоды>
<ПрочиеЕдиницыИзмерения>
<ОКЕИ>166ОКЕИ>
<Наименование>кгНаименование>
ПрочиеЕдиницыИзмерения>
<Характеристики>
<Код>1Код>
<Наименование>ЖёлтыеНаименование>
Характеристики>
<СчетаУчета>
<СчетУчетаОстатков>10.01СчетУчетаОстатков>
<СчетУчетаРасходов>26СчетУчетаРасходов>
СчетаУчета>
Номенклатура>
Первая строка была добавлена методом [[1c:объекты:ЗаписьXML:ЗаписатьОбъявлениеXML|ЗаписатьОбъявлениеXML()]] объекта [[1c:объекты:ЗаписьXML]]. Остальное сделала фабрика. Из интересных моментов можно отметить наличие пары дополнительных пространств имён помимо используемого нами. В них описываются базовые типы реквизитов, таких как строка.
Если требуется результат записать сразу в файл, можно воспользоваться соответствующими методами объекта [[1c:объекты:ЗаписьXML]].
===== Чтение объектов XDTO из файла =====
Процесс чтения проще чем процесс записи. Сначала выполняем непосредственно чтение с помощью объекта [[1c:объекты:ЧтениеXML]] и метода [[1c:общие:ФабрикаXDTO:ПрочитатьXML|ПрочитатьXML()]] фабрики:
РезультатXML = Новый ЧтениеXML;
РезультатXML.УстановитьСтроку(Результат);
НоменклатураСчитанная = МояФабрикаXDTO.ПрочитатьXML(РезультатXML, ТипОбъектаНоменклатура);
РезультатXML.Закрыть();
НоменклатураСчитанная.Проверить();
Как видим, [[1c:общие:ФабрикаXDTO:ПрочитатьXML|ПрочитатьXML()]] требует в качестве параметра указания типа принимаемого XDTO-объекта. Параметр не обязательный, при его отсутствии метод попытается сам определить тип объекта. В результате в переменную ''НоменклатураСчитанная'' поместится объект, аналогичный записанному ранее.
В последней строке кода мы воспользовались методом [[1c:объекты:ОбъектXDTO:Проверить|Проверить()]] объекта XDTO. Этот метод вызовет исключение, если считанный объект не соответствует схеме XML. Рекомендуется этот метод вызывать и непосредственно перед записью объекта, чтобы гарантировать что сохранённый файл будет корректным.
Обращение к реквизитам аналогично обращению к реквизитам фиксированных структур. Для реквизитов-списков можно воспользоваться итератором:
Для Каждого Штрихкод Из НоменклатураСчитанная.Штрихкоды Цикл
Сообщить(Штрихкод);
КонецЦикла;
Разумеется, содержимое считанного объекта можно менять. Впоследствии он может быть сохранён.
===== См. также =====
Объекты 1с и их типы:
[[1c:коллекции:Фиксированная структура|Фиксированная структура]], [[1c:глобальные_объекты:ФабрикаXDTO]], [[1c:общие:глобальные_объекты:СоздатьФабрикуXDTO]], [[1c:объекты:ТипОбъектаXDTO]], [[1c:объекты:ОбъектXDTO]], [[1c:объекты:СписокXDTO]], [[1c:объекты:КоллекцияСвойствXDTO]], [[1c:объекты:СвойствоXDTO]], [[1c:объекты:ЗаписьXML]], [[1c:объекты:ЧтениеXML]].
Связанные темы:
[[1c:общие:ПакетыXDTO|XDTO-пакеты]], [[https://ru.wikipedia.org/wiki/XML_Schema|XML Schema]], [[https://www.w3.org/TR/xmlschema-0/|XML Schema. Часть 0: Основные сведения (англ.)]] и [[http://citforum.ru/internet/xml/scheme/|перевод]], [[https://www.w3.org/TR/xmlschema-1/|XML Schema. Часть 1: Структуры (англ.)]], [[https://www.w3.org/TR/xmlschema-2/|XML Schema. Часть 2: Типы данных (англ.)]]
Другие статьи на эту тему:
* [[https://infostart.ru/public/98019/|Инфостарт:XDTO-пакеты, xml, xml schema]]
* [[http://1c-programmer-blog.ru/programmirovanie/xdto-v-1s.html]]
* [[http://infostart.ru/public/167459/|Инфостарт:XDTO - это просто]]
* [[https://infostart.ru/public/311011/|Инфостарт:Разбор XML документа - почти все возможные способы]]
Прочее:
{{backlinks>.#!1c:общие:xdto}}