Заказы на доработку 1С (сервис удаленной работы)

Хранилище

База знаний
Неназначенных незавершенных заказов: 2
Бесплатные отчеты, обработки, конфигурации, внешние компоненты для 1С Статьи, описание работы, методики по работе с 1С

Здравствуйте, гость ( Вход | Зарегистрироваться )



> XDTO-пакеты, xml, xml schema          
Vofka Подменю пользователя
сообщение 12.12.11, 15:44
Сообщение #1

У нас здесь своя атмосфера...
***********
Группа: Основатель
Сообщений: 13955
Из: Киев
Спасибо сказали: 4520 раз
Рейтинг: 3642.8

«[необходимо зарегистрироваться для просмотра ссылки] ште́ко будлану́ла бо́кра и курдя́чит бокрёнка»
(первая ассоциация, пришедшая в голову
после прочтения "мана" о XDTO-пакетах)


Приветствую, многоуважаемый all!

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

С чего начинается?..

С чего начинаются XDTO-пакеты для неискушенного разработчика? Для меня они начались с вопроса: "А что это еще за хренотень в дереве метаданных?" И еще я знал, что это что-то про xml. Но мы начнем не с этого. А с объекта ФабрикаXDTO. Как можно догадаться из названия, это фабрика объектов ([необходимо зарегистрироваться для просмотра ссылки] как XML Data Transfer Objects).

Небольшое лирическое отступление. Лучше понять, что такое "фабрика объектов", можно из замечательной книги "[необходимо зарегистрироваться для просмотра ссылки]" в частности, в разделе о шаблоне "[необходимо зарегистрироваться для просмотра ссылки]", или "[необходимо зарегистрироваться для просмотра ссылки]". Книга, хочу заметить, действительно стоящая, но мозголомная, скорее формата "справочник", а не "учебник". Вдобавок все, что там написано, сложно применимо к 1С. Когда-нибудь я разозлюсь и напишу здоровенную статью о шаблонах ([необходимо зарегистрироваться для просмотра ссылки]), а то досадно, что некоторые 1С-программистов [необходимо зарегистрироваться для просмотра ссылки]. Инструмент не должен стоять на пути человека к вершинам профессионализма. Но пока не об этом.

Итак, говоря простым языком, фабрика объектов - это некое "устройство", умеющее принять на входе описание объекта и сгенерировать по этому описанию объект определенного типа, "пригодный к употреблению". Или несколько. То есть это в прямом смысле фабрика: загрузили "чертеж", и она пошла штамповать "продукцию" по "чертежу" (для дотошных: "сырье" в этом случае ваше процессорное время, электричество и т.д.).



Тут я просто вынужден послать вас ознакомиться с хорошей статьёй о простых типах в XDTO с диска ИТС. Если бы это было целесообразно, я бы всю ее скопипастил сюда, но зачем? И все же один пример я оттуда возьму. Для наглядности.

Вот так в статье описывается работа с объектом "Структура":

структурныйТип = ФабрикаXDTO.Тип("http://www.1c.ru/demos/products", "Номенклатура");
номенклатура = ФабрикаXDTO.Создать(структурныйТип);
номенклатура.Наименование = "Ботинки женские";
номенклатура.ЗакупочнаяЦена = 1000;


Для этого примера я бы нарисовал такую диаграмму:



Обратите внимание, что объект "структурныйТип" (т.н. "чертеж") тоже был создан фабрикой, на основании "загадочных" строчек. Рассмотрим, что же это за строчки. Про метод "Тип" объекта "ФабрикаXDTO" синтакс-помощник пишет:

Цитата
Синтаксис:
Тип(<URIПространстваИмен>, <Имя>)

Возвращаемое значение:
Тип: ТипЗначенияXDTO; ТипОбъектаXDTO; Неопределено.

Описание:
Получение типа XDTO.


Не слишком информативно. Тем не менее понятно, что на основании какого-то пространства имен и имени типа метод "Тип" создает нам необходимый "чертёж". Про пространства имен можно почитать, например, в статье "[необходимо зарегистрироваться для просмотра ссылки]", или терзайте жужл запросом "[необходимо зарегистрироваться для просмотра ссылки]". Вкратце же скажу, что это некая область, в которой вы можете определить свои xml-теги, и они будут означать именно то, что вы в них закладывали при определении. Например, тег <table> в пространстве имен, определяющем HTML-документ, означает описание таблицы, а в вашем собственном он может означать, например, блок описания стола. Чтобы их не путать и нужны пространства имен.

Тут есть очень важный момент, который сначала вводит в заблуждение. Название пространства имен напоминает адрес страницы в интернете, и сразу же хочется посмотреть, что там такое по этому адресу. Так вот. Технически название может быть любым, но разработчики договорились, что все будут использовать в качестве названия пространства имен URL, по которому в интернете находится страница с описанием этого пространства имен, понятным человеку. К тому же так обеспечивается уникальность названий пространств имен, поскольку в интернете не может быть двух страниц с одинаковым адресом. И "ФабрикаXDTO" при генерации типа XDTO, конечно же, не лезет в интернет ни за какими данными. К сожалению, не все соблюдают правило о публикации человеческих описаний (сволочи!), и уж тем более нехорошо использовать адреса на чужих доменах (как в примере). Мало ли какую информацию фирма 1С воткнет со временем на страницу [необходимо зарегистрироваться для просмотра ссылки]. Это может вводить в заблуждение, поэтому в production-коде я настойчиво рекомендую использовать собственные домены и писать описания. Коллеги разработчики, давайте заботиться друг о друге.

Все же XDTO-пакеты

Поскольку мы выяснили, что данные о пространстве имен берутся не из интернета, возникает вполне резонный вопрос: откуда же тогда, черт побери?! И вот тут мы подходим к тому самому разделу "XDTO-пакеты" в дереве метаданных в конфигураторе. Внимательный читатель, наверное, заметил (если еще не забыл после моих лирических отступлений), что в примере мы использовали объект "ФабрикаXDTO", нигде его не создавая. Все верно, в глобальном контексте 1С есть такой объект (я бы сказал "синглтон"), который знает о куче разных пространств имен, уже описанных в конфигураторе и вообще в платформе. То есть для того, чтобы наш пример заработал, нам необходимо создать примерно такой XDTO-пакет:



То есть мы создали тип объекта "Номенклатура", в который добавили два свойства: "Наименование" и "ЗакупочнаяЦена". Обратите внимание, что при создании пакета мы задали ему то пространство имен, которое в дальнейшем будем использовать при создании объекта "структурныйТип". Если вы посмотрите конструктор свойств, то можете увидеть там много интересного. Например, для моего свойства "Наименование" я использовал тип "string (http://www.w3.org/2001/XMLSchema)". Запомните это пространство имен. В нем описаны все базовые типы, которые вы можете использовать в своих объектах, такие как "string", "int" и так далее. После того как мы добавили пакет, объект "ФабрикаXDTO" знает о нашем пространстве имен и описанных в нем типах.
Нужно помнить, что пространства имен, описанные в разделе дерева метаданных "XDTO-пакеты", доступны только на сервере. При попытке обратиться к ним из клиентского кода (так же как и при других ошибках) метод "Тип" вернет "Неопределено". Этот момент несколько раздражает при отладке, мне кажется, что лучше бы оно ругалось чем-нибудь вроде "Тип не найден", но "маємо те, що маємо".

В своих объектах вы можете использовать и собственные типы из вашего пространства имен. Например, давайте добавим единицы измерения:



В качестве типа для свойства "ЕдИзм" я установил тип "ЕдиницаИзмерения (http://www.1c.ru/demos/products1)", просто выбрав его из дерева определенных в конфигурации типов.
А вот код, который создает этот объект:

структурныйТип = ФабрикаXDTO.Тип("http://www.1c.ru/demos/products1", "Номенклатура1");
    номенклатура = ФабрикаXDTO.Создать(структурныйТип);
    номенклатура.Наименование = "Ботинки женские";
    номенклатура.ЗакупочнаяЦена = 1000;

    единицаТип = ФабрикаXDTO.Тип("http://www.1c.ru/demos/products1", "ЕдиницаИзмерения");
    единица = ФабрикаXDTO.Создать(единицаТип);
    единица.Наименование = "шт.";
    единица.Коэффициент = 1.5;

    номенклатура.ЕдИзм = единица;


Надеюсь, принцип понятен. Можете самостоятельно поиграться со свойствами, типами, объектами и прочим. Там есть куда "потыкать пальцем" и чего попробовать. А я тем временем продолжу.

Сериализировали-сериализировали

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

    ИмяФайла = "D:\Temp\struct.xml";
    МойXML = Новый ЗаписьXML;
    ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь);
    МойXML.ОткрытьФайл(ИмяФайла, ПараметрыЗаписиXML);
    МойXML.ЗаписатьОбъявлениеXML();

    ФабрикаXDTO.ЗаписатьXML(МойXML, номенклатура);

    МойXML.Закрыть();


На выходе мы получим вот такой файл:

<Номенклатура1 xmlns="http://www.1c.ru/demos/products1" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Наименование>Ботинки женские<Наименование>
<ЗакупочнаяЦена>1000<ЗакупочнаяЦена>
<ЕдИзм>
  <Наименование>шт.<Наименование>
  <Коэффициент>1.5<Коэффициент>
<ЕдИзм>
<Номенклатура1>


Теперь вы можете послать его друзьям по электронной почте, если, конечно, их интересуют женские ботинки. =)

Но поскольку объекты сериализуются, то они так же замечательно и десериализуются. Давайте попробуем:

    структурныйТип = ФабрикаXDTO.Тип("http://www.1c.ru/demos/products1", "Номенклатура1");

    ИмяФайла = "D:\Temp\struct.xml";
    МойXML = Новый ЧтениеXML;
    МойXML.ОткрытьФайл(ИмяФайла);

    номенклатура = ФабрикаXDTO.ПрочитатьXML(МойXML, структурныйТип);

    МойXML.Закрыть();

    Сообщить(номенклатура.ЕдИзм.Наименование);


Вы когда-нибудь разбирали xml-файлы построчно, вылавливая значки "больше"-"меньше" бесконечными "Найти" и "Сред/Лев/Прав"? А пользовались ли вы замечательным объектом "ЧтениеXML" для разбора файла по тегам, которые потом приходилось разгребать вручную в какую-нибудь структуру? Теперь, если у вас правильно описаны XDTO-пакеты и типы в них, вы можете загружать xml сразу в объект и дальше работать с ним как с объектом. На мой взгляд, это замечательно и удобно.
К тому же при загрузке xml-файла происходит его валидация на соответствие типу, и в случае ошибки метод вызывает исключение. Поэтому, конечно же, правильный код по загрузке xml будет такой:

    Попытка
        номенклатура = ФабрикаXDTO.ПрочитатьXML(МойXML, структурныйТип);
    Исключение
        Сообщить(ОписаниеОшибки());
        // еще какая-нибудь обработка исключения
        Возврат;
    КонецПопытки;


Что еще полезного можно получить из XDTO-пакетов? А вот что! Также мы можем очень просто выгружать объекты метаданных. В конфигурации есть пространство имен, в котором есть все типы XDTO присутствующих в конфигурации метаданных.

Добавим справочник "Клиенты", создадим в нем один элемент и напишем такой код:

    // Получим объект
    СпрКлиенты = Справочники.Клиенты;
    Выборка = СпрКлиенты.Выбрать();
    Пока Выборка.Следующий()  Цикл
        КлиентОбъект = Выборка.ПолучитьОбъект();
        Прервать;
    КонецЦикла;

    // Создадим ОбъектXDTO
    клиентыТип = ФабрикаXDTO.Тип("http://v8.1c.ru/8.1/data/enterprise/current-config", "CatalogObject.Клиенты");
    клиент = ФабрикаXDTO.Создать(клиентыТип);

    // Заполним ОбъектXDTO и сохраним его
    ЗаполнитьЗначенияСвойств(клиент,КлиентОбъект);

    ИмяФайла = "D:\Temp\сlient.xml";
    МойXML = Новый ЗаписьXML;
    ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь);
    МойXML.ОткрытьФайл(ИмяФайла, ПараметрыЗаписиXML);
    МойXML.ЗаписатьОбъявлениеXML();

    ФабрикаXDTO.ЗаписатьXML(МойXML, клиент);

    МойXML.Закрыть();


В первой части кода, там, где мы получаем объект, ничего интересного не происходит, мы просто получаем объект (весьма коряво, надо отметить, но для примера пойдёт).
Зато обратите внимание на пространство имен и имя объекта в строчке, где создается объект "клиентыТип". В пространстве имен "http://v8.1c.ru/8.1/data/enterprise/current-config" должны быть описаны все объекты метаданных конфигурации, в чем вы можете убедиться, если посмотрите его в конструкторе XDTO-пакетов.
Дальше уже знакомая процедура - сохранение объекта в XML.

Вот что получилось у меня:
Цитата
<?xml version="1.0" encoding="UTF-8" ?>
<CatalogObject.Клиенты
xmlns="http://v8.1c.ru/8.1/data/enterprise/current-config"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Ref>b0fc4df2-0a54-11e1-8797-ac728931524e</Ref>
<DeletionMark>false</DeletionMark>
<Code>000000001</Code>
<Description>Тестовый клиент 1</Description>
<ТипКлиента>непоняно</ТипКлиента>
</CatalogObject.Клиенты>


Как видите, тут есть все реквизиты, включая стандартные ("Наименование", "Код"), а также ссылка ("Ref") и пометка на удаление ("DeletionMark").

Естественно, этот файл также можно загрузить обратно в объект. Код, надеюсь, вы уже можете написать сами.

В помощь юному падавану-сериализатору в 1С есть объект "СериализаторXDTO". Он также представлен как "синглтон", доступный в глобальном контексте, и как отдельный тип. В принципе, строки:

    // Создадим ОбъектXDTO
    клиентыТип = ФабрикаXDTO.Тип("http://v8.1c.ru/8.1/data/enterprise/current-config", "CatalogObject.Клиенты");
    клиент = ФабрикаXDTO.Создать(клиентыТип);

    // Заполним ОбъектXDTO
    ЗаполнитьЗначенияСвойств(клиент,КлиентОбъект);


можно смело заменить на:

    // Создадим ОбъектXDTO и заполним его
    клиент = СериализаторXDTO.ЗаписатьXDTO(КлиентОбъект);


Код получился короче и работает более корректно. Например, если в справочнике "Клиенты" определены табличные части, то "ЗаполнитьЗначенияСвойств" с их заполнением не справится. А сериализатор - запросто. Теперь, когда (я надеюсь) вы понимаете основные принципы работы XDTO-пакетов, вы запросто разберетесь с тем, что еще можно делать с сериализатором. Да пребудет с вами сила синтакс-помощника. А я продолжу.

XDTO-пакет? [необходимо зарегистрироваться для просмотра ссылки]!

К этому моменту вы, наверное, задаете себе (а заодно и мне) вопрос: "Хорошо, ну вот у меня есть описанный в конфигурации тип в XDTO-пакете, есть xml, и все вроде бы хорошо. А что делать, если мне пришел какой-то новый xml, в другом формате, а я хочу работать с ним как с объектом? Опять конфигуратор открывать и описывать там тип?"
Конечно, без описания типа вам не обойтись. Но конфигуратор для этого не нужен. И тут нужно рассмотреть такую замечательную вещь, как xml schemа. XML-cхема - это как раз и есть описание типа, представленное (внимание!) в формате xml.
Давайте сделаем какой-нибудь небольшой XDTO-пакет, что-нибудь вроде этого:



А теперь нажмите на кнопку "Экспорт XML-схемы..." (выглядит как ящик с листиком бумаги и стрелочкой) и сохраните схему в файл address.xsd
У меня получилось вот что:

<xs:schema xmlns:tns="http://www.1c.ru/demos/products2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.1c.ru/demos/products2"
attributeFormDefault="unqualified" elementFormDefault="qualified">
<xs:complexType name="КлассификаторАдреса">
  <xs:sequence>
   <xs:element name="Город" type="xs:string"/>
   <xs:element name="Улица" type="xs:string"/>
   <xs:element name="НомерДома" type="xs:int"/>
   <xs:element name="НомерКвартиры" type="xs:int"/>
  </xs:sequence>
</xs:complexType>
</xs:schema>


Теперь удалите этот пакет из конфигурации, будто его и не было.
Попробуем прочитать схему и создать по ней объект. Вот код, который это делает:

    ФайлыXSD = Новый Массив();
    ФайлыXSD.Добавить("D:\Temp\adderss.xsd");
    МояФабрикаXDTO = СоздатьФабрикуXDTO(ФайлыXSD);

    адресТип = МояФабрикаXDTO.Тип("http://www.1c.ru/demos/products2", "КлассификаторАдреса");
    адрес = МояФабрикаXDTO.Создать(адресТип);
    адрес.Город = "Ленинград";
    адрес.Улица = "3-я улица Строителей";
    адрес.НомерДома = 25;
    адрес.НомерКвартиры = 12;


    ИмяФайла = "D:\Temp\address.xml";
    МойXML = Новый ЗаписьXML;
    ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь);
    МойXML.ОткрытьФайл(ИмяФайла, ПараметрыЗаписиXML);
    МойXML.ЗаписатьОбъявлениеXML();

    МояФабрикаXDTO.ЗаписатьXML(МойXML, адрес);

    МойXML.Закрыть();


Здесь мы для разнообразия не стали использовать глобальный объект "ФабрикаXDTO", а создали собственный функцией "СоздатьФабрикуXDTO". Если вы посмотрите в отладчике на нашу фабрику ("МояФабрикаXDTO"), то увидите, что в коллекции пакетов у нее всего два пакета: "http://www.w3.org/2001/XMLSchema" и "http://www.1c.ru/demos/products2", в отличие от "синглтона" "ФабрикаXDTO", где их существенно больше. В качестве бонуса мы получили то, что этот код может быть полностью исполнен на клиенте, так как не зависит от метаданных конфигурации.

На выходе я получил xml-файл, в который был сериализован мой объект:

<?xml version="1.0" encoding="UTF-8" ?> 
<КлассификаторАдреса
xmlns="http://www.1c.ru/demos/products2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Город>Ленинград</Город>
<Улица>3-я улица Строителей</Улица>
<НомерДома>25</НомерДома>
<НомерКвартиры>12</НомерКвартиры>
</КлассификаторАдреса>


Как вы видите, я поработал с объектом и сериализовал его без участия метаданных конфигурации. Таким образом, передавая вместе с xml-файлом также и XML-схему, вы можете быть уверенным, что тот, кто должен его получить, сможет разобраться, что с ним делать, а главное, как.
Пример десериализации приводить не буду, оставляю вам как самостоятельное упражнение.
Напоследок скажу, что можно выгрузить XML-схему всей вашей конфигурации, кликнув правой кнопкой по узлу "XDTO-пакеты". Результат получается поучительный, посмотрите.

Еще: если у вас есть xml-файл, с ним хочется поработать как с объектом, а XML-схему прислать никто не удосужился, вы можете воспользоваться замечательным [необходимо зарегистрироваться для просмотра ссылки]. (У себя я нашел его в папке "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\".) Пользоваться им очень просто: даете ему на вход xml, на выходе получаете xsd. Вообще-то этот xsd не всегда (или вообще никогда?) является файлом сразу же "готовым к употреблению" в 1С, но все равно это существенная помощь в создании XML-схемы.

Как видите, все оказалось достаточно просто.

На этом всё

Несмотря на то что статья оказалась неожиданно длинной, нельзя сказать, что все, что здесь описано, претендует на полноту. Пытливый исследователь XML-мира с легкостью напишет целую книгу по каждому абзацу этого небольшого обзора и еще ворох по тому, о чем здесь не сказано. Например, о том, что "вся эта кухня" тесно связана с web-сервисами. Тема обширна, так что дерзайте. Также я могу в чем-то заблуждаться, поэтому пишите комментарии - буду исправлять. Давайте учиться вместе.

А я желаю вам хорошего дня и хорошего кода. До новых встре

[необходимо зарегистрироваться для просмотра ссылки]


Не нашли ответа на свой вопрос?
Зарегистрируйтесь и задайте новый вопрос.


Ответить Новая тема
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

RSS Текстовая версия Сейчас: 24.04.24, 20:33
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!