Все будет сухо, без лирики и т.п.
Итак. Мне принесли задание. Подружить 1С с внешним сервисом по приему отчетности в виде xml файла.
Сторонний сервис имеет свой API по приему файлов, на выходе выдает некий код «батч», по которому я смогу вызвать еще одну функцию и получить по этому батчу, всю развернутую информацию по ошибкам.
Файл схема xsd небольшая, но типов данных много, на основе этой схемы полностью сформированный XML файл занимает что-то около 200Мб.
Дали ссылку на сайт, где можно узнать все остальное. Показывать ссылку не имеет смысла, т.к. доступ только после авторизации.
В итоге я имел на руках некий файл с расширением «xsd».
На тот момент я даже понятия не имел, что это и с чем и как его едят.
Дали какие-то пароли, логины, ссылку, куда все это выкладывать, и дали срок 3 недели.
Очень помог Инфостарт (не без этого, конечно, – огромное спасибо).
Для начала ниже материал, которым я пользовался, пока не завершил этот мини проект, и поэтому вот ссылки вам в помощь, которые могут понадобиться в дальнейшем, я думаю, это «маст-хэйв» для тех, кто хочет обучиться правилам XDTO:
//infostart.ru/public/167459/ - все три части
//infostart.ru/public/98019/ - похоже на «XDTO это просто», но сыроват
//infostart.ru/public/311011/ - написано просто и доступно
Что в итоге.
- Есть файл с правилами, ниже показана картинка в компактном виде, весь xsd файл можно увидеть во вложении.
Рис.1
Скажу, что на момент, когда я получил данный файл, я мог кое-как создавать типы XDTO. Читал статью «XDTO это просто» (все три части, конечно, не всё вкурил, как без этого).
И в итоге умел примерно такое:
Рис.2
(вырезка из другого кода)
То есть я мог создать тип «объектXDTO, если этот тип был расположен в дереве импортированной схемы в ветке «Типы объектов».Но на рисунке 1 выше видно, что все важные данные создаются только через ветку «свойства».
Рис.3
К примеру, на рис.3 видно, что у свойства «FirstName» один параметр «Name» является типом, ссылка на которую уводит в ветку «Типы объектов», а уже таааам указывается, что это за тип и что он в себе еще дополнительно содержит.
Рис.4
Как быть?
Что делать?
Как их прочитать?
Как на их основе мне создать тип «ОбъектXDTO», ведь через создать запись можно только если записываемый/создаваемый тип является типом «ОбъектXDTO»?
Что только не приходилось делать… я же умел создавать и записывать значения только если требуемые расположены в ветке «Типы объектов».
Даже дошел до того, что попробовал изменить схему.
Всё, что находилось в ветке «Свойства», я начал переносить в ветку «Типы объектов», начал создавать «туеву хучу» неправильных вещей, в итоге пришлось бросить весь гемор, пойти перекурить, и искать новые способы.
Попробовал все тестировать в «Liquid XML» - не получилось.
Потом попробовал все в «Visual Studio» - тоже …
Очень много звонил разработчикам этих схем, где им, наверное, думалось – «Вот чудик, он что, не знает про SOAP-ы, это же допотопный механизм обмена, странные он вопросы задает, хмм…» (кстати им тоже спасибо. открыли глаза 1С-нику).
В итоге.
В начале скажу, что у меня по условиям сбора данных есть некий первичный справочник список, в котором есть много реквизитов, которые необходимы для этого файла.
Данные собираются, фильтруются сортируются и в итоге я получаю готовую Таблицу значений.
Далее прохожу циклом эту таблицу и заполняю соответствующие реквизиты.
Итак, как я начал считывать XSD и создавать XML файлы.
Вначале считал пакет
Рис.5
Получил пакет в таком виде.
Рис.6
Далее мне нужно найти и спозиционироваться на свойстве «Records»
Вот она в дереве
Рис.7
Как это делается?
Скажу, что это как магия.
Пишем:
Рис.7
И мы получаем то значение, которое потом можем превратить в тип «ОбъектXDTO»
Вот код:
Рис.8
Получаем на выходе готовый нам нужный тип и делаем с ним все, что нужно.
К примеру, я должен пройтись циклом по реквизитам полученного объекта.
Рис.9
Просьба смотреть «не в воду», а в суть.
Тут главные строки это:
Рис.10
И (опять магия)
Рис.11
И т.д. далее, пока не получите что хотели.
Для получения каких-либо реквизитов свойства в схеме xsd пользуюсь такой конструкцией кода,
Но скажу, что видел и другие способы, тут, как говорится, дело ваше.
Рис.12
Результат рисунков с 7 по 12
Выглядит вот так в готовом файле:
Рис.13
И вот что я заметил (ну местные гуру, может, и знают давным-давно).
Это как бы и правила, и пометка.
Рассмотрим свойство «ContractCode»
Вот его описание:
Рис.14
Если это свойство имеет форму как «Элемент», то тогда код выглядит таким:
Рис.15
Т.е. я срази пишу значение в параметр, просто «= равно» и пошел.
Если свойство имеет форму как «Элемент», но он записан через знак «+»
Как вот тут
То его код выглядит немного иначе
Рис.16
Т.е. нужно сначала создать через фабрику этот тип, получить его подчиненные подтипы и уже им присваивать значения из ваших данных.
И в итоге получается вот что.
Если в схеме это свойство имеет форму «элемент»
То в готовом файле запишется такая запись:
Т.е. все будет записано внутри т.н. «тегов».
Далее если вы имеете в схеме такую связку значений и ее свойства:
рис.17
Т.е. у свойства «FundingType» есть подчиненный элемент «id», где его форма равна «Атрибут»
В этом случае код при написании НЕ изменится:
Замечу, что этот код похож на рис.16
Воот, а результат будет немножко другой:
Рис.18
Т.е. значение запишется сразу в сам «тег».
Далее.
Есть такое свойство, как «Gender»
Он в свою очередь имеет ссылку на другой тип:
Рис.19
А вот сам тип «GenderType»
Описан вот так.
Рис.20
Вот его свойства:
Рис.20.1
Тут говорится, что данный тип значения в целом равен типу «string», но он вариант у него «атомарный», т.е. имеет, скажем, «перечисление». И его перечисления, это
Тип ее:
Рис.20.2
Аналогично и с «F»
Теперь дилемма, как мне его получить и как его записать.
Вот ответ (сам искал полдня):
Рис. 21
Тут весь фокус в строке
Советую почитать про «Фасеты». Там все просто.
Ну и в завершение.
Собираем файл этими строками:
Тут лишь в конце стоит сказать один момент.
Принимающая сторона не передала значение «xmlns», пришлось ее искать и вписывать в начало файла, вот пример:
Думаю, на этом все!