XDTO — часть 3




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

94 Comments

  1. irishka77

    Спасибо!

    Reply
  2. Yashazz

    Вот за «Эта фабрика ничем особенным не отличается, при желании вы всегда можете создать такую же вручную.» уже можно запросто минуснуть. Между синглтоном и объектом, созданным через конструктор, есть существеннейшая разница. Автор, поправь, я верю, что ты просто неудачно выразился и эту разницу знаешь.

    Reply
  3. Evil Beaver

    (2) Yashazz, ну и какая разница с точки зрения использования одной и другой фабрик?

    Да, стандартная — это синглтон. Но мы можем сделать еще одну, по составу пакетов (а значит и функционалу) идентичную. Не понял суть претензии, поэтому не понял, как надо перефразировать.

    Если разница между глобальной фабрикой и такой же, но созданной через конструктор (с точки зрения чтения/записи XDTO) есть — просьба озвучить, наверное, я ее не знаю.

    upd: поправка. Глобальная переменная ФабрикаXDTO — это нифига не синглтон. Синглтон, это класс, у которого может быть только один экземпляр. Из википедии:

    «синглтон гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.»

    Так вот, фабрик в системе может быть сколько угодно много, а не одна. Просто одна из фабрик создана платформой автоматически.

    Reply
  4. kasper076

    Зачем нужно делать так:

    ОбъектModel = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);

    НоваяФабрикаXDTO = Новый ФабрикаXDTO(ОбъектModel);

    Почему нельзя сделать просто:

    НоваяФабрикаXDTO = СоздатьФабрикуXDTO(ИмяФайла);

    Reply
  5. maxis33

    Спасибо за труды, очень поучительно!

    Reply
  6. Evil Beaver

    (4) kasper076, Так делать можно, если схемы находятся в файлах. Если схемы лежат в макете, то так не получится. И потом, я просто забыл про этот метод. Спасибо, что напомнили 🙂

    Reply
  7. kasper076

    ИмяФайла = ПолучитьИмяВременногоФайла(«xsd»);

    Макет = ПолучитьМакет(«Макет»);

    Макет.Записать(ИмяФайла);

    Фабрика = СоздатьФабрикуXDTO(ИмяФайла);

    Reply
  8. Evil Beaver

    (7) kasper076, Ну да, разумеется. Только это уже не будет макет, а будет файл 🙂 И тут надо сделать еще удаление файла, предусмотрев возможные Попытки-Исключения и т.п. А реальных преимуществ, которые можно пощупать можно сказать и нет. Тем не менее, когда есть xml-схема в файле (а не в макете), то ваш способ с глобальным методом, несомненно, лучше всего. Опять же, при создании из xml-схемы нельзя настроить отображение имен XML в имена переменных языка 1С.

    Reply
  9. kasper076

    Можно ли программно создать/изменить ФабрикуXDTO?

    Reply
  10. Evil Beaver

    (9) kasper076, извините, не понял… А разве приведенным Вами же пример не отвечает на этот вопрос?

    Reply
  11. siwa99

    Спасибо за статью.Все разъяснено на доступном языке. Понятно,что тема раскрыта, но хотелось бы продолжения.

    Reply
  12. kasper076

    Я отвлекся чуток и не успел нормально сформулировать. Не ФабрикуXDTO, а модель данных (схему XML)? Но создать ее не путем создания XML-файла, а как если бы мы создавали ДеревоЗначений, например. Что-то типа .Колонки.Дабавить(«НоваяКолонка», ТипКолонки)

    Reply
  13. Evil Beaver

    модель данных — можно. Это объект XDTO с типом Model (точное URI пространства имен дано в статье). Поскольку, это объект XDTO, то его можно заполнить штатным образом. У него есть коллекция пакетов (свойство package), у пакетов перечень типов-значений и типов-объектов. Словом, программная модель того, что Вы можете сделать в конфигураторе — это класс Model.

    Reply
  14. kasper076

    А новый ТипXDTO создать, а затем ОбъектXDTO с этим типом?

    Reply
  15. Evil Beaver

    (14) kasper076, Какую задачу Вы хотите решить? Что должно быть в результате?

    Reply
  16. Sasha255n

    Спасибо

    Reply
  17. Yashazz

    (3) Насчёт синглтона — вопрос терминологии, что есть «создаваемое», и что есть предзаданное, но я не об этом. Насколько помню, типы, определённые в глобальной фабрике, могут расширяться засчёт создания пакетов XDTO, а при программном создании типы определяются прямо при создании и расширяться «после» уже не могут. Я верно помню?

    Reply
  18. Sergey03

    Спасибо, нужная статья.

    Reply
  19. Evil Beaver

    (17) Yashazz, ну в целом все верно. Только в стандартной фабрике типы тоже не могут расширяться после создания фабрики. Она создается при старте Предприятия и содержит, как я писал — платформенные пакеты, плюс пакеты из ветки ПакетыXDTO в метаданных. После создания глобальной Фабрики (запуска в режиме 1С:Предприятия) поменять состав типов нельзя.

    Reply
  20. dk666dk

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

    рез = Запрос.Выполнить().Выгрузить();

    Тип = ФабрикаXDTO.Тип(«http://v8.1c.ru/8.1/data/enterprise/current-config»,»CatalogRef.Номенклатура»);

    Для каждого стр из рез Цикл

    сс = ФабрикаXDTO.Создать(Тип,(стр.ссылка));

    НоваяФабрикаXDTO.ЗаписатьXML(ЗаписьXML,сс);

    КонецЦикла;

    Выдает следующее сообщение:

    {Форма.Форма.Форма(216)}: Ошибка при вызове метода контекста (ЗаписатьXML)

    НоваяФабрикаXDTO.ЗаписатьXML(ЗаписьXML,сс);

    по причине:

    Несоответствие типов XDTO:

    Тип ‘{http://v8.1c.ru/8.1/data/enterprise/current-config}CatalogRef.Номенклатура’ не найден

    Тип принадлежит пакету, отсутствующему в фабрике типов XDTO

    Reply
  21. Evil Beaver

    (20) dk666dk, Вы создаете тип одной фабрикой, а пишете — другой. Зачем Вам несколько фабрик? Пользуйтесь какой-то одной.

    Reply
  22. AlexBar

    Автору респект за статью. Есть вопрос. Возможно ли с помощью инструментов XDTO решить следующую задачу:

    Преобразуем ДокументОбъект в XML:

    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку(«UTF-8»);
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    ЗаписатьXML(ЗаписьXML, ДокументОбъект, НазначениеТипаXML.Явное);
    XMLТекстОбъекта = ЗаписьXML.Закрыть();
    

    Обратное преобразование можно выполнить следующим образом:

    ЧтениеXML = Новый ЧтениеXML();
    ЧтениеXML.УстановитьСтроку(XMLТекстОбъекта);
    ДокументОбъект = ПрочитатьXML(ЧтениеXML);
    

    Если в конфигурации нет никаких изменений, то данные процедуры работают без проблем и исключительно быстро.

    Однако стоит только в объекте метаданных изменить последовательность реквизитов, удалить или добавить какой-нибудь реквизит, все, записанная ранее XML версия документа больше не прочитается.

    Приходится парсить XML объекта чтобы получить его данные.

    Возможно ли решить данный вопрос с помощью инструментов XDTO?

    Например создаем из объекта метаданных объект XDTO 1, из XML старого объекта создаем объект XDTO 2, заполняем значения свойств из XDTO 2 в XDTO 1, преобразуем объект XDTO 1 в объект информационной базы.

    Я понимаю что представление описываю скорее всего не верно, но важна сама суть.

    Спасибо.

    Reply
  23. Evil Beaver

    (22) AlexBar, Ну если я правильно понял, то у Вас будут 2 варианта объекта в виде XML, и Вы предполагаете переносить между ними свойства явно «Объект1.Наименование = Объект2.Наименование»? Если так, то все будет работать.

    Reply
  24. dk666dk

    ага спс, ток все равно не пойму как объекты записать. Более конкретно стоит задача: есть ТаблицаЗначений из Полей СправочникСсылка.Номенклатура и Количество вот не могу никак загнать это в XML. буду благодарен за кусочек кода 🙂

    Reply
  25. Evil Beaver

    (24) dk666dk,

    // Запись
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ВашаТаблицаЗначений);
    
    // Чтение
    ВашаТаблицаЗначений = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип(«ТаблицаЗначений»));
    
    

    С вас вобла под пивасик 🙂

    Reply
  26. dk666dk

    премного благодарен, если с оренбурга, то не вопрос 🙂

    Reply
  27. AlexBar

    (23)

    А сработает ли конструкция ЗаполнитьЗначенияСвойств(ОбъектXDTO1, ОбъектXDTO2)? Потому-что перебирать все реквизиты не есть айс…

    Reply
  28. Evil Beaver

    Не уверен, что во всех случаях поможет. Надо экспериментировать.

    Перебрать реквизиты можно через метаданные типа XDTO. Т.е. получить тип объекта, а у ТипаОбъектаXDTO есть коллекция Свойства.

    Reply
  29. AlexBar

    (28)

    Пытаюсь получить ОбъектXDTO

    ЧтениеXML = Новый ЧтениеXML();
    ЧтениеXML.УстановитьСтроку(XMLТекстОбъекта);
    ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
    

    Получаю такую же ошибку, как если бы я прочитал XML

    ДокументОбъект = ПрочитатьXML(ЧтениеXML);
    
    Reply
  30. Evil Beaver

    (29) AlexBar, разумеется. Глобальный метод «ПрочитатьXML» — это просто обертка над стандартной фабрикой. Структура «старого» объекта у Вас неизвестна, ее надо где-то «надыбать», создать на ее основе фабрику и интерпретировать старые и новые структуры вручную.

    Reply
  31. Evil Beaver

    Вернее, в (30) я был не прав. Покажите, что содержится у вас в переменной XMLТекстОбъекта?

    Если там не указан атрибут xsi:type, то чтение через ФабрикаXDTO.ПрочитатьXML() должно возвращать объект XDTO без выдачи ошибок. Если же там тип указан, то читать нужно явно передавая второй параметр для ФабрикаXDTO.ПрочитатьXML(), а в нем указывать тип «старой» структуры.

    Reply
  32. AlexBar

    (31)

    Прикладываю файл объекта из УПП.

    Reply
  33. Evil Beaver

    (32) AlexBar, смотрите: в файле явно указан тип — xsi:type=»DocumentObject.РеализацияТоваровУслуг». Если вы будете читать такой файл без указания второго параметра метода ФабрикаXDTO.ПрочитатьXML(), то структура файла должна в точности совпадать со структурой документа «РеализацияТоваровУслуг». Если файл у Вас в старой структуре, а в базе уже новая, то Вам понадобится пакет XDTO, в котором прописана структура старого документа. Либо, Вы можете удалить данный атрибут и прочитать файл, как anyType (без данного атрибута и без 2-го параметра метода ФабрикаXDTO.ПрочитатьXML()). Перечитайте еще раз статью № 3.

    Reply
  34. AlexBar

    (33)

    >Если вы будете читать такой файл без указания второго параметра метода ФабрикаXDTO.ПрочитатьXML()

    Из справки: Тип: ТипЗначенияXDTO; ТипОбъектаXDTO

    Я имею прикладной тип: Тип(«ДокументОбъект.ИмяОбъекта»), в нашем случае: Тип(«ДокументОбъект.РеализацияТоваровУслуг»), как из него получить ТипЗначенияXDTO или ТипОбъектаXDTO?

    >Вы можете удалить данный атрибут

    Это значит что нужно снова парсить текст. Суть вопроса и заключается в том: можно ли найти метод, позволяющий избежать сложного разбора текста старого объекта?

    Огромное спасибо за то, что уделяете мне свое время!

    Reply
  35. Evil Beaver

    (34) AlexBar, копайте синтакс-помощник в сторону СериализаторXDTO.XMLТипЗнч(). Парсить текст лучше всего документом DOM. Создаете, удаляете атрибут, получаете ЧтениеУзловDOM и это «Чтение» скармливаете фабрике.

    Я бы делал так:

    1. Читал заведомо старый XML построителем DOM

    2. Удалял атрибут типа

    3. Читал фабрикой нетипизованный объект anyType

    5. Перебирал свойства этого объекта и писал в новый формат.

    Reply
  36. AlexBar

    Вывод: от парсинга и перебора свойств (реквизитов) не уйти.

    Тогда в свете моего вопроса XDTO ничем не облегчит решение вопроса.

    Reply
  37. kiruha

    Спасибо за публикацию, очень подробно описано создание, но непонятно про чтение

    Обхожу ОбъектModel . Получил дочерний ОбъектXDTO. Сериализуемый

    У соответствующего объекта 1С есть свойство «Имя»

    У ОбъектXDTO — свойство name. Получил.

    Как программно узнать , что name это «Имя» ?

    Только методом тыка на совпадение значения свойства или есть «нормальный» способ?

    Reply
  38. kiruha

    И непонятно с anyType

    >>Для этого в методе ФабрикаXDTO.ПрочитатьXML есть второй параметр — тип объекта.

    Делаю по совету

    Например сохраняю схему компоновки с параметром НазначениеТипаXML.Явное

    Тут же пытаюсь ее прочитать с параметром

    ТипСхемы = ФабрикаXDTO.Тип(«http://v8.1c.ru/8.1/data-composition-system/schema», «DataCompositionSchema»);

    ОбъектModel = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML,ТипСхемы);

    и вываливается ошибка на несоответствие схемы

    Без явного указания типа все нормально считывается, но полно anyType для объектов, про которые известно что они сериализуемы

    Reply
  39. Evil Beaver

    (43) kiruha, кусок кода записи и точный текст ошибки можете дать?

    Reply
  40. kiruha

    задумался,переделал

    ОбъектModel = ФабрикаXDTO.ПрочитатьXML(ПервыйПараметр,ТипСхемы);

    ПервыйПараметр — было ЧтениеУзловDom(разрешается по синтаксису) переписал код, чтобы было ЧтениеXML

    Хм — и чудо — ошибка исчезла, anyType исчезли )

    спасибо )

    а вот как мне сопоставить свойства, например

    У СхемаКомпоновкиДанных есть свойство ВычисляемыеПоля

    У соотв объектаXDTO DataCompositionSchema есть свойство calculatedField

    не сложно убедиться что они соотв друг другу

    А как определить это программно ?

    Может есть справочник соответствий или метод ?

    Reply
  41. kasper076

    (45) Может чтонить типа XMLТипЗнч() ?

    Reply
  42. Evil Beaver

    (45) kiruha,

    ПервыйПараметр — было ЧтениеУзловDom(разрешается по синтаксису) переписал код, чтобы было ЧтениеXML

    Хм — и чудо — ошибка исчезла, anyType исчезли.

    Странно, так не должно быть. Дайте кусок кода. Если это и правда так, то это ошибка платформы. Объекты чтения XML должны быть полностью взаимозаменяемы и не должны приводить к разному поведению.

    У СхемаКомпоновкиДанных есть свойство ВычисляемыеПоля

    У соотв объектаXDTO DataCompositionSchema есть свойство calculatedField

    Какую задачу Вы решаете? Объекты системы компоновки все полностью поддерживаются платформой. calculatedField в «ВычисляемоеПоле» лекго превращается глобальным СериализаторомXDTO. Где-то выше в комментариях мой ответ насчет ТаблицыЗначений. С вычисляемым полем то же самое. Как правило, «сопоставить» свойства XDTO и прикладного объекта может только Сериализатор.

    Reply
  43. kasper076

    Evil Beaver, а если как в случае у AlexBar схема источник не соответствует схеме приемнику. Как при обходе свойств СхемыКомпоновкиДанных сопоставить им свойства из ОбъектModel?

    Reply
  44. kiruha

    (47)

    Какую задачу Вы решаете? Объекты системы компоновки все полностью поддерживаются платформой. calculatedField в «ВычисляемоеПоле» лекго превращается глобальным СериализаторомXDTO.

    Видимо я недостаточно понятный пример привел

    есть объект XDTO DataCompositionSchema — сериализируется СхемаКомпоновкиДанных

    у него набор свойств, например dataSet(P.S>свойства начинаются с маленько буквы,типы с большой ) — список XDTO

    элемент списка — DataSetUnion(и др) сериализируется (имена свойств и типов в общем похожи , но не совпадают)

    Оба объекта прекрасно сериализируются, но

    модель языка

    СхемаКомпоновкиДанных — св-во НаборыДанных — НаборДанныхОбъединениеКомпоновкиДанных

    модель XDTO

    DataCompositionSchema — св-во dataSet — DataSetUnion

    Можно по DataCompositionSchema получить СхемаКомпоновкиДанных , по DataSetUnion получить НаборДанныхОбъединениеКомпоновкиДанных, а вот как получить соответствие названий свойств

    св-во dataSet — св-во НаборыДанных

    //P.S>

    Чтобы не СКД — др пример —

    Если у объекта есть несколько реквизитов с типом номенклатура, то в модели XDTO я могу получить элемент объекта,подчинен элемент номенклатуры, но не могу понять к какому реквизиту объекта отнести этот элемент

    Reply
  45. Evil Beaver

    (49) kiruha, Сопоставить автоматом — никак. Но у меня вопрос — а зачем это вообще нужно? Для чего их вдруг надо вообще куда-то сопоставлять? Какая задача решается?

    (48) kasper076, аналогично — никак. Автоматом не получится. О соответствии знает только алгоритм сериализации. Платформенных объектов — платформенный сериализатор, о ваших объектах — только вы.

    И опять же: а зачем это?

    Reply
  46. kiruha
    Но у меня вопрос — а зачем это вообще нужно?

    для универсальных обработок

    Самый простой пример — получить свойства справочника(имеется ввиду объект платформы СправочникСсылка, а не реквизиты объекта конфигурации) программно (это задача в примитивной трактовке)

    XDTO их показывает, но в специфической форме

    Ладно, все понял.

    Спасибо за помощь.

    Reply
  47. Evil Beaver

    (51) kiruha, Вам виднее, но мне кажется, что это неправильный подход к механизму. Он изначально не подразумевает автоматических сопоставлений объектам языка. Это просто более удобный доступ к XML.

    Reply
  48. kiruha

    Возможно не подразумевал. Но они сделали обмен схемами СКД на XML, сериализовали множество объектов не имеющих отношение к обмену, а 8.3 выгрузку форм в XML. Некая тенденция очевидна

    Возможно ошибаюсь — спорить не буду , т.к. не по теме публикации

    Reply
  49. Evil Beaver

    Да понятно, что тенденция есть. Но принцип такой, что объекты-объектами, но сериализацию выполняет некий алгоритм, который знает, как объект интерпретировать. Отсюда опять же мой вопрос — зачем для платформенных пакетов XDTO нужно делать то, что уже и так есть? Чего не хватает?

    Reply
  50. scanner1980

    Здравствуйте.

    Есть импортированный пакет в 1С из внешнего файла (от поставщика) примерно следующего содержания:

    Пакет

    Свойства

    Свойство1

    Свойство2

    Файл xml на выходе должен быть:

    <?xml version=»1.0″ encoding=»windows-1251″?>

    <Свойство1>

    <Свойство2>Какой-то текст</Свойство2>

    </Свойство1>

    никак не пойму как сделать свойства на выходе вложенными (если это вообще возможно)?

    Reply
  51. Stamper

    занимались реализацией SOAP сервиса для связи с мобильными платформами. так вот основной трафик (так уж вышло) давали наименования полей! и это не удивительно: передаём-то XML, и наименование каждого узла повторяется. так что делайте наименования полей покороче =)

    Reply
  52. PrinzOfMunchen

    (54) огромное спасибо за данную «трилогию» статей!

    А будет ли продолжение? Например про применение преобразований xml — xslt? Очень красивая и мощная вещь всё таки))

    Reply
  53. Yuriy.MW

    Спасибо за статью.

    Может подскажите маленький вопросик.

    В базе1 есть пакет XDTO: URI http://www.bla.bla и типом Taxes

    И есть веб-сервис.

    Веб сервис возвращает значение

     РезXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(«http://www.bla.bla», «Taxes»));
    //заполнение свойств
    Возврат РезXDTO;

    XDTO вручную выгружен в D:Taxes.xsd.

    В базе2:

    //Прокси = Новый WSПрокси(…
    Рез = Прокси.GetTaxes();
    
    ФайлыXSD = Новый Массив();
    ФайлыXSD.Добавить(«D:Taxes.xsd»);
    МояФабрикаXDTO = СоздатьФабрикуXDTO(ФайлыXSD);
    
    Запись = Новый ЗаписьXML;
    Запись.ОткрытьФайл(«D:	x.xml»);
    МояФабрикаXDTO.ЗаписатьXML(Запись,Рез,»Taxes»,»http://www.bla.bla»,,НазначениеТипаXML.Явное); //тут ошибка
    Запись.Закрыть();

    Показать

    При записи возникает ошибка: Несоответствие типов XDTO:

    Тип ‘{http://www.bla.bla}Taxes’ не найден

    Тип принадлежит пакету, отсутствующему в фабрике типов XDTO

    Хотя, в тоже время без проблем создается объект:

    РезТест = МояФабрикаXDTO.Создать(МояФабрикаXDTO.Тип(«http://www.bla.bla», «Taxes»));

    И если в табло выполнить Рез.Тип() то URI и имя совпадают с ожидаемыми.

    В чем ошибка?

    Reply
  54. Evil Beaver

    Попробуйте записать не через

    МояФабрикаXDTO.ЗаписатьXML

    , а через

    WSПрокси.ФабрикаXDTO
    Reply
  55. kembrik

    Попробовал Ваш метод созданий собственных фабрик (с моделью в Макете), споткнулся, не посмотрите причину?

    Один из пакетов в макете:

    <package targetNamespace=»http://Vorobiev_s/current-config»>
    <property name=»CatalogObject_Номенклатура» localName=»CatalogObject.Номенклатура»>
    <typeDef xsi:type=»ObjectType»>
    <property name=»IsFolder» type=»xs:string» lowerBound=»0″ localName=»ЭтоГруппа»/>
    <property name=»Ref» type=»xs:string» lowerBound=»0″ localName=»Ссылка»/>
    <property name=»DeletionMark» type=»xs:string» lowerBound=»0″ localName=»ПометкаУдаления»/>
    <property name=»Parent» type=»xs:string» lowerBound=»0″ localName=»Родитель»/>
    <property name=»Code» type=»xs:string» lowerBound=»0″ localName=»Код»/>
    <property name=»Description» type=»xs:string» lowerBound=»0″ localName=»Наименование»/>
    <property name=»Артикул» type=»xs:string» lowerBound=»0″/>
    <property name=»НаименованиеПолное» type=»xs:string» lowerBound=»0″/>
    <property name=»БазоваяЕдиницаИзмерения» type=»xs:string» lowerBound=»0″/>
    <property name=»НомерГТД» type=»xs:string» lowerBound=»0″/>
    </typeDef>
    </property>
    <property name=»NewDataSet»>
    <typeDef xsi:type=»ObjectType» ordered=»false» sequenced=»true»>
    <property xmlns:d5p1=»http://Vorobiev_s/current-config» ref=»d5p1:CatalogObject_Номенклатура» lowerBound=»0″ upperBound=»-1″/>
    </typeDef>
    </property>
    </package>

    Показать

    Потом пробуем создать NewDataSet и спотыкаемся

    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.УстановитьСтроку(ПолучитьМакет(«Модель»).ПолучитьТекст());
    ОбъектModel = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
    НоваяФабрикаXDTO = Новый ФабрикаXDTO(ОбъектModel);
    
    Для Каждого Пакет из НоваяФабрикаXDTO.Пакеты Цикл
    Если Пакет.URIПространстваИмен = «http://Vorobiev_s/current-config» Тогда
    
    СписокНоменклатуры = НоваяФабрикаXDTO.Создать(Пакет.URIПространстваИмен,»NewDataSet»);
    

    Показать

    Несоответствие типов XDTO:

    Тип ‘{http://Vorobiev_s/current-config}NewDataSet’ не найден

    Тип не определен

    Где я напортачил :)? В отладчике в КорневыеСвойства «NewDataSet» присутствует, явно обращаюсь я к нему неправильно, какой будет синтаксис обращения в этом случае?

    Reply
  56. xzorkiix

    (35)

    1. Читал заведомо старый XML построителем DOM

    Простите, а это как?

    Тут с веб-сервисом работаю через HttpСоединение, чтобы ответ сериализовать фабрикой успешно нужно немного подправить полученный ответ сервиса.

    Reply
  57. xzorkiix

    (47)

    Странно, так не должно быть. Дайте кусок кода. Если это и правда так, то это ошибка платформы. Объекты чтения XML должны быть полностью взаимозаменяемы и не должны приводить к разному поведению.

    Наткнулся на те же грабли ЧтениеУзловDOM заменил на ЧтениеXML. Ошибка ушла. (1С:Предприятие 8.2 (8.2.18.61))

    Функция ПолучитьОбъектФабрикиИзXML(Фабрика, ТипXDTO, Источник) Экспорт
    
    Перем Результат, Путь;
    
    //
    // Текст Источника, например
    //
    // <?xml version=’1.0′ encoding=’UTF-8′?>
    // <soapenv:Envelope xmlns:soapenv=»http://schemas.xmlsoap.org/soap/envelope/»>
    //  <soapenv:Body>
    //   <tns:Y_MM_SRV_WSI_GET_SRV_LINE_LISTResponse xmlns:tns=»urn:sap-com:document:sap:rfc:functions»>
    //   <!— содержание ответа сервиса —>
    //   </tns:Y_MM_SRV_WSI_GET_SRV_LINE_LISTResponse>
    //  </soapenv:Body>
    // </soapenv:Envelope>
    //
    // для успешной конвертации в Объект XDTO через Фабрику — файл должен быть
    //
    // <?xml version=’1.0′ encoding=’UTF-8′?>
    // <Y_MM_SRV_WSI_GET_SRV_LINE_LISTResponse xmlns=»urn:sap-com:document:sap:rfc:functions»>
    //  <!— содержание ответа сервиса —>
    // </Y_MM_SRV_WSI_GET_SRV_LINE_LISTResponse>
    //
    
    Если ТипЗнч(ТипXDTO) = Тип(«Строка») Тогда
    ТипXDTO = ПолучитьТипXDTO(Фабрика,,ТипXDTO);
    КонецЕсли;
    
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.ОткрытьФайл(Источник);
    
    ПостроительDOM = Новый ПостроительDOM;
    ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
    ЧтениеXML.Закрыть();
    
    СписокЭлементовDOM = ДокументDOM.ПолучитьЭлементыПоИмени(ТипXDTO.URIПространстваИмен, ТипXDTO.Имя);
    Если СписокЭлементовDOM.Количество() Тогда
    
    Если СписокЭлементовDOM[0].ЕстьДочерниеУзлы() Тогда
    
    ДокDOM = Новый ДокументDOM(ТипXDTO.URIПространстваИмен, ТипXDTO.Имя);
    
    Для Каждого ЭлементXDTO Из СписокЭлементовDOM[0].ДочерниеУзлы Цикл
    ДокDOM.ЭлементДокумента.ДобавитьДочерний(ЭлементXDTO.КлонироватьУзел(Истина));
    КонецЦикла;
    
    Путь = ПолучитьИмяВременногоФайла(«xml»);
    
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.ОткрытьФайл(Путь);
    ЗаписьDOM = Новый ЗаписьDOM;
    ЗаписьDOM.Записать(ДокDOM,ЗаписьXML);
    ЗаписьXML.Закрыть();
    
    КонецЕсли;
    
    // Здесь падает в ошибку
    //
    // ЧтениеУзловDOM = Новый ЧтениеУзловDOM;
    // ЧтениеУзловDOM.Открыть(ДокDOM);
    //
    // Результат = Фабрика.ПрочитатьXML(ЧтениеУзловDOM,ТипXDTO);
    //
    
    ЧтениеXML.ОткрытьФайл(Путь);
    Результат = Фабрика.ПрочитатьXML(ЧтениеXML,ТипXDTO);
    
    КонецЕсли;
    
    Возврат Результат;
    
    КонецФункции

    Показать

    Reply
  58. xzorkiix

    (60) kembrik, если конечно ещё актуально.

    Для Каждого Пакет из НоваяФабрикаXDTO.Пакеты Цикл
    Если Пакет.URIПространстваИмен = «http://Vorobiev_s/current-config» Тогда
    СписокНоменклатуры = НоваяФабрикаXDTO.Создать(Пакет.URIПространстваИмен,»NewDataSet»);

    заменить последнее на

    ТипXDTO = Пакет.Получить(«NewDataSet»);
    Если ТипЗнч(ТипXDTO) <> Неопределено Тогда
    СписокНоменклатуры = НоваяФабрикаXDTO.Создать(ТипXDTO);
    КонецЕсли;
    Reply
  59. kembrik

    (63) xzorkiix, Спасибо, уже разобрался совместно с автором статей, у меня пакет кривой был, починили — взлетело ))

    Reply
  60. Alex_1066

    Evil Beaver, вопрос: Есть пакет XDTO, в котором есть элемент, имеющий тип «Список» (т.е., в данном примере, имеющий значения 0…-1). При попытке обращения к такому объекту программно возникает непонятная ситуация. Если в списке имеется один элемент, то он имеет тип «ОбъектXDTO», если два и более, то «СписокXDTO»… я уж не говорю про то, если этого элемента просто не будет (список может быть и нулевым). Т.е., что я хочу сказать — невозможно обратиться к данному списку через механизм коллекции «Для каждого..», например. Получается, что необходимо для каждого списка выяснять, сколько же он там в этот раз содержит элементов и следовательно, считает ли система это вообще списком? Так что ли? Т.е., без вот такой структуры

    Если ТипЗнч(НашДокумент.ЭлементСписка) = Тип(«СписокXDTO») Тогда …
    

    не обойтись, что ли?

    Reply
  61. Evil Beaver

    Список, если заявлен в схеме, как список, то всегда является списком. У вас где-то ошибка. Приведите код считывания XML из файла и преобразования в XDTO

    Reply
  62. Alex_1066

    Вот код:

     ТипОбъектаВыписка = ФабрикаXDTO.Тип(«http:\www.avent.comBPSBclient», «BPSBclient»);
    
    ИмяФайла = «e:МояБазаVip.xml»;
    МойXML = Новый ЧтениеXML;
    МойXML.ОткрытьФайл(ИмяФайла);
    
    Попытка
    Выписка = ФабрикаXDTO.ПрочитатьXML(МойXML, ТипОбъектаВыписка);
    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат;
    КонецПопытки;
    
    МойXML.Закрыть();
    
    Если ТипЗнч(Выписка.Statement.CreditDocuments.Document) = Тип(«СписокXDTO») Тогда
    
    Для каждого Документ из Выписка.Statement.CreditDocuments.Document Цикл
    Сообщить(Документ.Payer.Name);
    КонецЦикла;
    ИначеЕсли ТипЗнч(Выписка.Statement.CreditDocuments.Document) = Тип(«ОбъектXDTO») Тогда
    Документ =  Выписка.Statement.CreditDocuments.Document;
    Сообщить(Документ.Payer.Name);
    КонецЕсли;
    

    Показать

    При просмотре в отладчике, «Document» (настроен как список в XDTO пакете)принимает различные типы, поэтому предпринята попытка анализа данного факта.. Что здесь не так и как обойтись без анализа каждого такого списка? Ведь по идее система должна понимать определённые типы значений однозначно…

    Reply
  63. Evil Beaver

    (67) Alex_1066, чтение выполняется с указанием типа, значит должна понимать настройку схемы, т.е. видеть, что это всегда список. Странно, вроде все верно. А схему дадите (прикрепленным файлом)?

    Reply
  64. Alex_1066

    Да, конечно, вот и он…

    Reply
  65. Evil Beaver

    (69) Alex_1066, я вроде не вижу ошибок в схеме и в коде. Досконально можно сказать, только колупаясь в отладчике. Но это уж сами. Скорее всего, мы что-то упускаем из вида. Списковые свойства при чтении, если указан считываемый тип должны считываться правильно. Если ничего не получится сделать — создайте простой пример воспроизведения и отправьте в 1С на testplatform@1c.ru (адрес точно не помню, как то так звучит).

    Хотя… стоп-стоп.

    А что за тип такой: ФабрикаXDTO.Тип(«http:\www.avent.comBPSBclient», «BPSBclient»)?

    В схеме нету такого типа.

    Reply
  66. Alex_1066

    (70) спасибо за помощь, но… после полученных замечаний и очередной попытки пришёл в полное уныние… Наверное я чего-то глобально всё-таки не понял. Если в предыдущем примере была явная ошибка в указании типа, но, тем не менее, объект создавался каким-то образом??? После же указания типа стало вываливать сообщение «Ошибка при вызове метода контекста (ПрочитатьXML):Ошибка преобразования данных XDTO…», причём, если считываешь файл такого плана

    <?xml version=»1.0″ encoding=»UTF-8″?>
    <Контрагент xmlns=»http:\www.avent.com» xmlns:xs=»http://www.w3.org/2001/XMLSchema» xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»>
    <Account>12312312312</Account>
    …
    </Контрагент>

    , то система создаёт объект нормально, т.к. наверное видит пространство имён, а если вот такой

    <?xml version=»1.0″ encoding=»UTF-8″?>
    <Контрагент>
    <Account>3012052670019</Account>
    …
    </Контрагент>

    ,

    то уже ни в какую.. Но в чём тогда у меня путаница… Я так понимаю, что механизм позволяет обрабатывать любые XML при наличии к нему схемы XML.

    Reply
  67. Evil Beaver

    (71) Alex_1066, что такое схема XML? Это однозначное описание того, что может быть в документе. Очень строгое и дотошное описание. В первом случае система видит, что Контрагент принадлежит пространству имен. А во втором — это неизвестно какой контрагент. Пространства нет, мало ли «контрагентов» на свете.

    Файл не читается, выдается ошибка потому, что ваш файл не соответствует схеме. Это не «тот» файл который система хочет, вот и все. Зачем вам второй вариант текста? Это лажа, пользуйтесь первым.

    Reply
  68. Alex_1066

    (72)Спасибо, Evil Beaver. Теперь понятно, где собака порылась 🙂

    Reply
  69. Evil Beaver

    (73) Alex_1066, спасибо не булькает (народная мудрость), а так — пожалуйста 🙂

    Reply
  70. НебаЖитель

    Может кто подсказать по теме? Уже много времени потратил, а так и не разобрался( http://forum.infostart.ru/forum26/topic91743/

    Reply
  71. Evil Beaver

    (75) НебаЖитель, ответил в той ветке.

    Reply
  72. Алексей777

    Спасибо за статьи! Все очень доступно, понятно и легко.

    Reply
  73. ВладАн

    Evil Beaver, я надеюсь на Вас)) подскажите пожалуйста по теме http://forum.infostart.ru/forum26/topic92232/

    ПС: ну или кто-то другой может подсказать?

    Reply
  74. Evil Beaver

    (78) ВладАн, увы, не подскажу.

    Reply
  75. ВладАн

    (79) Спасибо, что посмотрели.

    Reply
  76. ZLENKO

    (25) Как же мне этого не хватало в 1С 8.1:

    // Запись
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ВашаТаблицаЗначений);
    
    // Чтение
    ВашаТаблицаЗначений = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип(«ТаблицаЗначений»));
    Reply
  77. inv7

    Evil Beaver, подскажите, пожалуйста:

    по команде

    ФабрикаXDTO.ЗаписатьXML(ЗаписьXML,root);

    в файле xml формируется запись:

    <root xmlns=»out» xmlns:xs=»http://www.w3.org/2001/XMLSchema» xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance» ID=»59″>

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

    <root ID=»59″>

    Не могу этого добиться. Как это сделать при помощи ФабрикаXDTO, или использовать простую запись XML?

    Reply
  78. inv7

    в предыдущем сообщении оформление съело текст

    Evil Beaver, подскажите, пожалуйста:

    по команде

    ФабрикаXDTO.ЗаписатьXML(ЗаписьXML,root);

    в файле xml формируется запись:

    <root xmlns=»мПродажи» xmlns:xs=»http://www.w3.org/2001/XMLSchema» xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance» ID=»59″>

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

    <root ID=»59″>

    Не могу этого добиться. Как это сделать при помощи ФабрикаXDTO, или использовать простую запись XML?

    Reply
  79. inv7

    есть

    <element xmlns=»out» xmlns:xs=»http://www.w3.org/2001/XMLSchema» xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance» ID=»59″>

    надо

    <element ID=»59″>

    Reply
  80. inv7

    есть

    <root xmlns=»out» xmlns:xs=»http://www.w3.org/2001/XMLSchema» xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance» ID=»59″> 

    надо

    <root ID=»59″> 
    Reply
  81. Evil Beaver

    (85) inv7, XDTO, насколько я знаю, всегда будет писать объявления схем. Если не нужны, пишите ручками.

    Ну и еще мысль, записывайте поток XDTO не в ЗаписьXML, а в ЗаписьУзловDOM, потом из DOM выбросьте все, что вам не нужно и запишите DOM уже в XML.

    Reply
  82. inv7

    (86) спасибо за ответ. очень надеялся, что я чего-то недопонимаю. придется писать ручками. идею с DOM попробую, если интересно, отпишу результат. еще раз благодарю.

    Reply
  83. MakcTLT63

    Спасибо автору.

    Очень помогло в изучении.

    Reply
  84. Evil Beaver

    (87) inv7, да, отпишите, пожалуйста. Должно работать, никуда не денется.

    (88) MakcTLT63, и Вам спасибо за отзыв.

    Reply
  85. lesenoklenok

    Спасибо за интересную статью, все три части прочитала, очень хорошо описано.

    Reply
  86. xIvanx

    Нигде не могу найти ответ, как при помощи XDTO прочитать XML, в котором есть элементы, содержащие атрибут и текстовое значение.

    Пример:

    <parameter name=»log-timestamp»>14550C1B0ED-14550BEB879-27</parameter>

    При чтении через фабрику получаю только свойство name (см. скриншот). Как добраться до значения?

    Reply
  87. Evil Beaver

    (91) xIvanx, текстовое значение будет обозначено свойством __content.

    Обратите внимание, во второй части цикла статей написано про свойство «локальное имя». Посмотрите туда, там увидите этот «__content».

    Получается, что код чтения будет такой:

    НекийОбъектXDTO.log_timestamp = ///
    НекийОбъектXDTO.__content = //
    Reply
  88. xIvanx

    (92) Пробовал так, ожидаемо ругается: Поле объекта не обнаружено (__content)

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

    Чтение объекта типа: {http://пространствоимен}Status — [3,7]
    Проверка дополнительного свойства:
    форма: Элемент
    имя: code
    Ответ = ФабрикаXDTO.ПрочитатьXML(Чтение, ResponseТип);
    по причине:
    Ошибка преобразования данных XDTO:
    Чтение объекта типа: {http://пространствоимен}Status — [3,7]
    Проверка дополнительного свойства:
    форма: Элемент
    имя: code
    по причине:
    Ошибка проверки данных XDTO:
    Структура объекта не соответствует типу: {http://пространствоимен}Status

    Показать

    Вроде всем хорош XDTO, а такую простую вещь никак не могу осилить.

    Reply
  89. Evil Beaver

    (93) xIvanx, Ну во-первых, XDTO хорош не всем 🙂

    По вашей проблеме — у вас явное несовпадение по схеме. Т.е. ваш файл схеме не соответствует. Ищите расхождение, может там длина несовпадает или еще что-то.

    Reply
  90. kpakaguJL

    Спасибо за статьи — очень интересно и главное полезно написано!

    Подскажите, пожалуйста, есть XML файлы и написанная под них схема. файл служит для передачи определенного документа.

    то есть тег «Number» это номер, ну и так далее.

    собственно вопрос — где и каким образом лучше всего указать соответствие между тегом и Реквизитом документа. и как быть с табличной частью?

    спасибо большое

    Reply
  91. Evil Beaver

    (95) kpakaguJL,

    где и каким образом лучше всего указать соответствие между тегом и Реквизитом документа. и как быть с табличной частью

    Собственно нигде. Прописать в коде явным образом ОбъектXDTO.Number = Документ.Номер

    Чтобы этого не делать, можно воспользоваться стандартной сериализацией (но тогда схема будет не вашей, а 1С-овской)

    ЗаписатьXML(ЗаписьXML, ДокументОбъект)

    Иными словами, соответствие нигде не указывается, а прописывается в коде ручками, до самой последней мелочи.

    Reply
  92. kpakaguJL

    Спасибо большое!

    И еще такой вопросик при выгрузке — получаю в файле что-то вроде

    <?xml version=»1.0″ encoding=»UTF-8″?>
    <ORDRSP xmlns=»http://www.obzhora.ordrsp.ua» xmlns:xs=»http://www.w3.org/2001/XMLSchema» xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»>
    <NUMBER>ББ000003472</NUMBER>
    бла бла бла

    можно ли как-то надоумить его выгружать чистые теги без доп настроек с URL, как то так:

    <?xml version=»1.0″ encoding=»UTF-8″?>
    <ORDRSP>
    <NUMBER>ББ000003472</NUMBER>
    бла бла бла
    Reply
  93. Evil Beaver

    (97) kpakaguJL, как-то не вижу разницы)

    Reply
  94. xCyrix

    Здравствуйте!

    Помогите пожалуйста разобраться.

    есть схема sxd (cheki.xsd)

    есть файл xml (purchases.xml) который нужно прочитать по схеме cheki.xsd

    читаю:

    ТипФайлов = «purchases»;

    ЧтениеXML = Новый ЧтениеXML;

    ЧтениеXML.ОткрытьФайл(«C:purchases.xml»);

    ФайлыXSD = Новый Массив();

    ФайлыXSD.Добавить(«c:cheki.xsd»);

    ЗагрузкаФабрикаXDTO = СоздатьФабрикуXDTO(ФайлыXSD);

    ТипЧеки = ЗагрузкаФабрикаXDTO.Тип(«http://www.crystals.ru», ТипФайлов);

    Чеки = ЗагрузкаФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ТипЧеки);

    СписокЧеков = Чеки.purchase;

    Индекс = 0;

    Чек = СписокЧеков.Получить(Индекс);

    ЧтениеXML.Закрыть();

    СвойствоПозицияЧека = Чек.positions.Свойства().Получить(«position»);

    ПозицииЧека = Чек.positions.ПолучитьСписок(СвойствоПозицияЧека);

    СвойствоОплатаЧека = Чек.payments.Свойства().Получить(«payment»);

    ОплатыЧека = Чек.payments.ПолучитьСписок(СвойствоОплатаЧека);

    и в крайней строке ОплатыЧека = Чек.payments.ПолучитьСписок(СвойствоОплатаЧека); получаю ошибку:

    {ВнешняяОбработка.ЧтениеXML.Форма.Форма.Форма(32)}: Ошибка при вызове метода контекста (ПолучитьСписок)

    ОплатыЧека = Чек.payments.ПолучитьСписок(СвойствоОплатаЧека);

    по причине:

    Несоответствие свойства и элемента данных XDTO:

    Свойство: ‘payment’

    Свойство не является списковым

    значит position у него является списковым, а payment вдруг перестал быть списковым!!! это как так???

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *