Механизм XDTO для 1С: Предприятие 7.7 на базе MSXML 6.0


В число средств платформы 1С:Предприятие, релиза 8.Х входит замечательный во всех отношениях набор методов и классов, объединенный под общим названием «XML Data Transfer Objects» или, кратко: «XDTO». Как и следует из его названия, цель этого механизма в том, чтобы на уровне платформы осуществлять поддержку процедур представления данных информационной базы в формат XML-файла и чтения данных XML-файла в объекты информационной базы.

Разработчикам на платформе 1С: Предприятие 7.7 предоставлено выходить из положения каким-то образом самостоятельно…

… в том числе, за счет разного рода программных оболочек над внешними компонентами, в частности, системной библиотекой MSXML 6.0.

Процедура СериализоватьОбъект()
    Перем хмлПарсер, хмлНаборСхем, хмлКорень, хмлУзел;
 
    Товары = СоздатьОбъект("Справочник.Номенклатура");
    Товары.ВыбратьЭлементы();
 
    Если Товары.ПолучитьЭлемент() = 1 Тогда
        Попытка
            Результат = глмХМЛ.СоздатьЭлементДокумента(хмлПарсер, хмлНаборСхем, хмлКорень,
                "ROOT", "windows-1251") * глмХМЛ.СериализоватьОбъект(Товары.ТекущийЭлемент(),
                    хмлПарсер, хмлНаборСхем, хмлУзел, "myType:Справочник." + Товары.Вид(), "");
        Исключение
            Возврат;
        КонецПопытки;
        Если Результат = 1 Тогда
            хмлКорень.appendChild(хмлУзел);
                глмХМЛ.ВывестиДокументВФайл(хмлПарсер, стрИмяФайла);
        Иначе
            Сообщить("Ошибка!", "!");
        КонецЕсли;
    Иначе
        Сообщить("В справочнике ""Номенклатура"" не задано ни одного элемента", "!");
    КонецЕсли;
КонецПроцедуры

<?xml version="1.0" encoding="windows-1251"?>
    <ROOT xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Справочник.Номенклатура xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:myType="http://my.org/torg">
            <Ref>{"B","0","0","69","0","0","         1   "}</Ref>
            <Код>Р-000001</Код>
            <Наименование>Товар №1</Наименование>
            <Родитель 
                xsi:type="myType:Справочник.Номенклатура" view="">
                    {"B","0","0","69","0","0","         0   "}
            </Родитель>
            <Владелец></Владелец>
            <Вес>          0.000</Вес>
            <Вид xsi:type="myType:Справочник.ВидыТоваров" view="">
                {"B","0","0","26","0","0","         0   "}
            </Вид>
            <КВК>          0.000</КВК>
            <Производитель xsi:type="myType:Справочник.Производители" view="">
                {"B","0","0","83","0","0","         0   "}
            </Производитель>
            <КодСоответствия>      </КодСоответствия>
            <ПроцентСписания>          0.000</ПроцентСписания>
            <АссортиментМороженое>          0.000</АссортиментМороженое>
            <АссортиментПФ>          0.000</АссортиментПФ>
            <ТипФасовки xsi:type="myType:Перечисление.ТипыФасовки" view="Весовой">
                {"E","0","0","258","0","0","       256   "}
            </ТипФасовки>
        </Справочник.Номенклатура>
    </ROOT>

Процедура ПрочитатьОбъект()
    Перем хмлПарсер, хмлНаборСхем;
 
    Если глмХМЛ.ПрочитатьДокументИзФайла(хмлПарсер,
        хмлНаборСхем, "", стрИмяФайла) = 1 Тогда
 
            хмлУзел = хмлПарсер.documentElement.childNodes(0);
            МенеджерОбъекта1С = "";
 
            Если глмХМЛ.ПрочитатьОбъект(МенеджерОбъекта1С,
                хмлПарсер, хмлНаборСхем, хмлУзел, 0) = 1 Тогда
 
                    Сообщить(МенеджерОбъекта1С);
            КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Одной из особенностей данной оболочки является возможность «на лету» применять XSLT-шаблоны трансформации данных при построении обменов данными между различными конфигурациями на базе различных платформ 1С: Предприятие.
стрШаблон = "<?xml version=""1.0"" encoding=""WINDOWS-1251""?>
|<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
| xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xs=""http://www.w3.org/2001/XMLSchema""
| xmlns:myType=""http://my.org/buh"">
|
|     <xsl:template match=""/"">
|
|         <xsl:for-each select=""ROOT/CatalogObject.Номенклатура"">
|             <CatalogObject.Номенклатура>
|                 <xsl:copy-of select=""*""/>
|             </CatalogObject.Номенклатура>
|         </xsl:for-each>
|
|         <xsl:for-each select=""ROOT/Справочник.Номенклатура"">
|             <CatalogObject.Номенклатура>
|                 <IsFolder>false</IsFolder>
|                 <Ref><xsl:value-of select=""Ref""/></Ref>
|                 <xsl:element name=""Parent"">
|                     <xsl:attribute name=""xsi:type"">
|                         <xsl:text>myType:Справочник.Производитель</xsl:text>
|                     </xsl:attribute>
|                     <xsl:value-of select=""Производитель""/>
|                 </xsl:element>
|                 <Code><xsl:value-of select=""Код""/></Code>
|                 <Description><xsl:value-of select=""concat(Наименование,' ',Вес)""/></Description>
|                 <xsl:element name=""НоменклатурнаяГруппа"">
|                     <xsl:attribute name=""xsi:type"">
|                         <xsl:text>myType:Справочник.Вид</xsl:text>
|                     </xsl:attribute>
|                     <xsl:value-of select=""Вид""/>
|                 </xsl:element>
|             </CatalogObject.Номенклатура>
|         </xsl:for-each>
|
|     </xsl:template>
|
|</xsl:stylesheet>
|";

Процедура ПередатьОбъект()
    Перем хмлПарсер, хмлНаборСхем, хмлКорень, хмлШаблон, хмлУзел;
 
    Товары = СоздатьОбъект("Справочник.Номенклатура");
    Товары.ВыбратьЭлементы();
 
    Если Товары.ПолучитьЭлемент() = 1 Тогда
        Попытка
            Результат = глмХМЛ.СоздатьЭлементДокумента(хмлПарсер, хмлНаборСхем,
                хмлКорень, "ROOT", "windows-1251") * глмХМЛ.ПрочитатьДокументИзСтроки
                    (хмлШаблон, хмлНаборСхем, "", стрШаблон);
 
            Результат = Результат * глмХМЛ.СериализоватьОбъектРекурсивно(Товары.ТекущийЭлемент(),
                хмлПарсер, хмлКорень, хмлНаборСхем, хмлШаблон, "", "myType", 
                    "myType:Справочник." + Товары.Вид(), "");
 
        Исключение
            Возврат;
        КонецПопытки;
 
        Если Результат = 1 Тогда
            глмХМЛ.ВывестиДокументВФайл(хмлПарсер, стрИмяФайла);
        Иначе
            Сообщить("Ошибка!", "!");
        КонецЕсли;
    Иначе
        Сообщить("В справочнике ""Номенклатура"" не задано ни одного элемента", "!");
    КонецЕсли;
КонецПроцедуры

<!--?xml version="1.0" encoding="windows-1251"?-->
<CatalogObject.Номенклатура xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:myType="http://my.org/buh">
    <IsFolder>false</IsFolder>
    <Ref>{"B","0","0","33","0","0","     17197001"}</Ref>
    <Parent xsi:type="myType:Справочник.Производитель"></Parent>
    <code>12962</code>
    <НоменклатурнаяГруппа xsi:type="myType:Справочник.Вид">{"B","0","0","3782","0","0"," 0 "}</НоменклатурнаяГруппа>
</CatalogObject.Номенклатура>

Читать структуру данных объектов информационной базы методами работы с метаданными и применять к полученным XML-объектам XSLT-преобразования — не единственный способ строить узлы XML-файлов синхронизации данных. В качестве исходных данных, программная оболочка может принимать файлы-описания WEB-сервиса приложения WSDL.
Процедура Сформировать()
    Перем хмлПарсер, хмлНаборСхем, хмлКорень, хмлШаблон, хмлУзел;
 
    глмХМЛ.СоздатьЭлементДокумента(хмлПарсер, хмлНаборСхем, хмлКорень, "ROOT", "windows-1251");
 
    сзОписаниеСообщенияСервиса = глмХМЛ.НайтиОписаниеСообщенияСервиса(ксКаталогПроекта2, 
        "GetBusinessEntityByGuid");
 
    ИмяФайлаСхемы = сзОписаниеСообщенияСервиса.Получить("ИмяФайла");
    URIПространстваИмен = сзОписаниеСообщенияСервиса.Получить("ПространствоИмен");
    Имя = сзОписаниеСообщенияСервиса.Получить("Имя");
    Префикс = сзОписаниеСообщенияСервиса.Получить("Префикс");
 
    глмХМЛ.ДобавитьСхемуИзФайлаРекурсивно(хмлНаборСхем, URIПространстваИмен, 
        ксКаталогПроекта2, ИмяФайлаСхемы);
 
    глмХМЛ.ПространстваИмен.ДобавитьЗначение("ws", URIПространстваИмен);
    Имя = СтрЗаменить(Имя, Префикс + ":", "");
    хмлОписаниеТипа = хмлНаборСхем.getSchema(URIПространстваИмен).elements.itemByName(Имя).type;
    Имя = глмХМЛ.ПространстваИмен.Получить(URIПространстваИмен) + ":" 
        + СтрЗаменить(Имя, Префикс + ":", "");
 
    Для Н = 1 По глмХМЛ.ПространстваИмен.РазмерСписка() Цикл
        Префикс = глмХМЛ.ПространстваИмен.ПолучитьЗначение(Н, URIПространстваИмен);
        глмХМЛ.ДобавитьАтрибут(хмлПарсер, хмлПарсер.documentElement, "xmlns:" 
            + Префикс, URIПространстваИмен);
    КонецЦикла;
 
    хмлЗапрос = глмХМЛ.ПостроитьУзелПоОписаниюТипа(хмлПарсер, хмлНаборСхем, хмлОписаниеТипа, Имя);
    хмлКорень.appendChild(хмлЗапрос);
    глмХМЛ.ВывестиДокументВФайл(хмлПарсер, стрИмяФайла);
 
КонецПроцедуры

<?xml version="1.0" encoding="windows-1251"?>
<ROOT xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bs="http://api.vetrf.ru/schema/cdm/base"     xmlns:dt="http://api.vetrf.ru/schema/cdm/dictionary/v2" xmlns:ws="http://api.vetrf.ru/schema/cdm/registry/ws-definitions/v2">
    <ws:getBusinessEntityByGuidRequest>
        <bs:guid/>
    </ws:getBusinessEntityByGuidRequest>
</ROOT>