Консалтинг и автоматизация в области управления
эффективностью банковского бизнеса

Журнал ВРМ World

Практика применения XML в приложениях B2P

В настоящее время в различных изданиях уделяется много внимания языку межпрограммного взаимодействия - XML. Мы также не оставляем эту тему без внимания, поскольку XML играет важную роль в технологии разработки программных продуктов нашей компании. В первую очередь - это задача доставки данных из различных OLTP-приложений в Хранилище информации. Системы автоматизации многофилиального банка или крупной корпорации зачастую представляют собой набор программных средств от различных производителей. Выполняя их интеграцию с целью построения единого информационного пространства территориально распределенной организации, нами накоплен некоторый практический опыт применения языка XML в создании приложений класса B2P, которым мы готовы поделиться со своими коллегами. Следует отметить, что эта статья может быть тяжела для восприятия для тех, кто только начинает использовать XML. Но она может быть интересна специалистам, которые на практике применяют XML и уже имеют собственное мнение о принципах построения XML-документов.

Вначале описаны общие принципы построения XML-документов. Далее представлены базовые принципы программной реализации обработчиков XML-документов. Отдельно приводится обоснование выбранного языка программирования. Приложение содержит примеры форматов XML-документов.

Принципы построения XML-документов

Общие правила оформления

Согласно стандарту XML первой строкой любого XML-документа должна быть следующая:

<?xml version="1.0" encoding="windows-1251" ?>

Здесь windows-1251 означает, что все буквы в тегах XML-документа будут либо латинскими, либо русскими в кодировке ANSI.

Далее возможно еще несколько управляющих инструкций. В частности, задающих систему и конфигурацию из или для которой сформирован XML-документ. А затем следует один корневой тег с набором вложенных тегов, составляющих собственно содержание документа.

Объектный подход

Все данные в XML-документах оформляются в виде объектов прикладных классов. В XML-документе объект представляется в виде последовательности из открывающего тега - имени класса объектов, последовательности тегов - данных объекта и закрывающего тега. Для повышения визуальной читаемости XML-документа часть данных объекта может быть представлена в виде атрибутов в открывающем теге. Рассмотрим все вышесказанное на примере:

<Счет Номер="407028105000000000001">
   <БалансовыйСчет>40702</БалансовыйСчет>
</Счет>

В приведенном примере <счет> - название класса прикладных объектов, <номер> и <балансовыйсчет> - данные объекта. Причем, для того чтобы сразу было понятно, какой именно счет передается, <номер> оформлен как атрибут открывающего тега.

Несколько слов о DOM и DTD

Объектный подход к построению XML-документов логично приводит к мысли об использовании таких SDK как DOM или, по крайней мере, DTD. Но мы отказались и от того и от другого.

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

DTD как раз позволяет описывать сложные регулярные структуры. Но в нем отсутствуют возможности контроля типов значений атрибутов объекта. В результате все равно требуется внешнее описание структур объектов и типов их атрибутов.

И DOM и DTD не являются устоявшимися стандартами. Сейчас наблюдаются совершенно разные течения как в сторону полного отказа от их использования и замены чем-то другим, так и в сторону коренных переделок существующего. Но практически никого не устраивает то, что есть. Значит, оно будет изменено или заменено. И нам придется переделывать всю свою реализацию, что недопустимо. Ну и, наконец, в нашей системе существует собственное мощное хранилище метаданных, намного перекрывающее возможности DOM и DTD.

Сложные данные

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

Для обеспечения этой возможности классы прикладных объектов разделяются на две группы - собственно прикладные объекты и списки таких объектов. Опять же для повышения визуальной читаемости каждый объект-список в XML-документе имеет как минимум один атрибут открывающего тега -<количество>, который показывает, сколько прикладных объектов входит в этот список.

При формировании XML-документа должен соблюдаться принцип чередования объектов этих групп. Т.е. данными объекта-списка, кроме простых данных, могут быть только прикладные объекты, но не объекты-списки. И наоборот данными прикладного объекта могут быть только объекты-списки. Опять же рассмотрим пример:

<Документ Номер="12345">
   <Плательщик>ТОО Рога и копыта</Плательщик>
   <Получатель>ООО Интерсофт Лаб</Получатель>
   <Основание>Оплата по договору №1</Основание>
   <Проводки Количество="2">
       <Проводка>
           <СчетДебета>407028105000000000001</СчетДебета>
           <СчетКредита>407028107000000000002</СчетКредита>
           <Сумма>100000.00</Сумма>
       </Проводка>
       <Проводка>
           <СчетДебета>407028105000000000001</СчетДебета>
           <СчетКредита>701078103000000000001</СчетКредита>
           <Сумма>1000.00</Сумма>
       </Проводка>
   </Проводки>
</Документ>

В примере приведен банковский документ, содержащий две проводки. В этом случае одним из данных прикладного объект класса <документ> является объект-список класса <проводки>. Данными этого объекта, в свою очередь, являются прикладные объекты класса <проводка>.

Бинарные данные

Некоторые объекты могут содержать бинарные данные. Примерами могут служить графические образцы подписей клиентов, ключи электронных подписей, документы в формате MS Word и т.п. Эти данные не выводятся непосредственно в XML-документ. Они формируются как отдельные файлы в специально отведенном каталоге, а в XML-документ помещаются ссылки на них. При разборке XML-документа все происходит в обратном порядке - по ссылке находится файл и данные из него помещаются в атрибут объекта.

Правила формирования и разборки XML-документов

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

Разборка XML-документа осуществляется одним из стандартных XML-парсеров. Обработка данных осуществляется в соответствии со следующими принципами:

  • при отсутствии фиктивного тега обрабатывается ровно один объект - тот, чей тег является корневым, и только после закрытия его тега;
  • при наличии фиктивного тега объект считается полностью сформированным и подлежащим обработке только после закрытия тега второго уровня;
  • при наличии фиктивного тега на втором уровне не должно быть иных тегов, чем открывающие теги объектов.
Поясним на примере с документом:

<Сеанс>
   <Документ Номер="12345">
       :
       <Проводки Количество="2">
           <Проводка>
              :
           </Проводка>
           <Проводка>
              :
           </Проводка>
   </Документ>
      :
   <Документ Номер="12345">
      :
   </Документ>
   <Номер>1</Номер>
</Сеанс>

Тег <Сеанс> является фиктивным и игнорируется при разборке XML-документа.

Закрывающие теги </Проводка>, также как и закрывающие теги простых данных не приводят ни к какой обработке, так как закрывают теги третьего и более уровней.

Закрывающие теги </Документ> завершают формирование объектов класса <документ> со всеми его данными и вызывают соответствующую обработку. Например, создание объекта в БД и выполнение проводок по нему.

Тега <Номер> в правильном документе быть не должно, т.к. в системе отсутствует класс объектов <номер> .

Корректным является также XML-документ, содержащий эту и только эту информацию:

<Документ Номер="12345">
      :
   <Проводки Количество="2">
       <Проводка>
          :
       </Проводка>
       <Проводка>
          :
       </Проводка>
</Документ>

Программная реализация

Основные достижения

Для обработки XML-документов написана библиотека классов на языке Python. Каждый класс обеспечивает интерфейс для отдельного объекта системы между XML-представлением объекта и представлением его в БД системы. Все интерфейсы унифицированы. Также реализованы несколько утилит, которые, используя указанную библиотеку, обеспечивают:

  • визуальное представление находящихся в системе данных;
  • возможность формирования XML-документа, представляющего собой копию БД всей системы или ее части;
  • визуальное представление такого XML-документа в виде иерархии объектов системы;
  • загрузку данных из XML-документа в БД системы;
  • выполнение операции над объектом, причем как сам объект, так и сведения об операции передаются в виде XML-документа.

Основные свойства библиотеки классов

Классы в библиотеке реализованы попарно: отдельный объект - список объектов. Это позволяет поддержать принцип чередования простых объектов и их списков.

Данные объектов

Все классы имеют обязательное свойство obj_name, являющееся XML-тегом, соответствующим этому объекту или списку.

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

Для обеспечения читабельности XML-документа часть атрибутов может представляться не вложенными тегами, а атрибутами базового тега объекта. Такие атрибуты помещаются в специальный список, используемый утилитами формирования XML-документов.

Для обеспечения правильного порядка следования тегов в XML-документе и для правильного порядка обработки атрибутов-списков при чтении данных из XML-документа также используется специальный список. Атрибуты из этого списка первыми выводятся в XML-документ и первыми обрабатываются при чтении из него.

Все атрибуты, являющиеся бинарными данными, также помещаются в отведенный для них специальный список.

Методы объектов

Все классы в библиотеке в обязательном порядке имеют два метода:

  • get - считать объект из БД;
  • put - положить объект в БД.
Для возможности универсального использования оба метода не имеют параметров. Вся необходимая информация перед вызовом должна быть помещена в атрибуты объекта.

Остальные методы являются необязательными. Как правило, для простых классов определены следующие унифицированные методы:

  • exists - проверить наличие объекта в системе;
  • insert - создать объект в системе;
  • update - изменить свойства существующего объекта;
  • delete - удалить объект из системы.
Также для каждого прикладного объекта может быть реализовано произвольное количество специфических методов. Например, для счета это open и close. Эти методы могут иметь произвольное количество параметров, особенно в случае, когда данных, содержащихся в атрибутах объекта, не хватает для выполнения операции.

Выполнение операций

Каждый класс в библиотеке имеет зарезервированный атрибут operation. Этот атрибут имеет фиксированный тэг в XML-документах - <Операция> и используется утилитой загрузки объектов из XML-документов. Логика следующая - если атрибут operation не пуст, то выполнить указанную в нем операцию.

Атрибут operation всегда представляет собой объект-список, в котором находятся параметры операции. Этот список имеет также один собственный атрибут - имя операции. Параметры у каждой операции всегда именованные. Т.е. параметр операции представляет собой объект с парой атрибутов - имя и значение.

В настоящей реализации имена операции и параметров латинские и прямо соответствуют имени метода класса объектов и именам параметров этого метода. По результатам применения возможно легко заменить латинские названия на соответствующие им русские.

Пример описания операции открытия счета:

<Счет Номер="407028105000000000001">
   <Операция Метод="open">
       <ПараметрОперации Код="date">
           <Значение>1-01-2000</Значение>
       </ПараметрОперации>
   </Операция>
</Счет>

Особенности форматов XML-документов, накладываемые системой и библиотекой классов

В системе существует возможность создания структур объектов нескольких категорий. Все такие объекты имеют однотипное представление в XML-документах. А именно:

<КатегорияОбъектов Тип="КодСтруктурыОбъекта">
   Теги, соответствующие атрибутам, присутствующим во всех объектах категории
   Теги, соответствующие атрибутам, определенным для указанной структуры
</КатегорияОбъектов>

Вот список существующих на данный момент категорий:

  • Документы;
  • Субъекты;
  • ШтатныеЕдиницы;
  • Операции;
  • ФинансовыеИнструменты;
  • Справочники;
  • Счета.

Выбор языка программирования

Цели выбора

При выборе языка программирования для реализации библиотеки прикладных классов, преследовались следующие цели:

  1. минимизация времени разработки библиотеки;
  2. простота сопровождения библиотеки;
  3. простота использования библиотеки не только для обработки XML-документов, но и для прочего прикладного использования;
  4. необходимость иметь высокоуровневый язык для расширения системы и при этом минимизировать количество применяемых при разработке языков.
К языку также предъявлялись следующие требования:
  1. Если это новый язык, то простота его освоения специалистами, имеющими опыт программирования на языках типа C, C++, Pascal, etc.
  2. Возможность легкого встраивания программ на этом языке в систему. Сюда входит возможность вызова из системы как целых модулей реализованных на этом языке, так и отдельных функций из модулей, а также возможность вызова функций системы из программ на этом языке.
  3. Наличие <родной> библиотеки по работе с XML.
  4. По возможности открытость языка, т.е. чтобы язык не являлся собственностью и корпоративным стандартом какой-то одной фирмы.
  5. Наличие в языке мощных библиотек по работе со строками, списками, etc.
  6. Гибкость языка, возможность легкого добавления в него новой функциональности.
  7. Скорость работы.
  8. Желательная кроссплатформенность.

Итоги выбора

Исходя из поставленных целей, круг поиска сразу сузился до интерпретируемых языков. Из интерпретируемых языков многие были отброшены из-за неудовлетворения одному или нескольким требованиям. В результате после рассмотрения нескольких вариантов, в частности Java, Basic, Perl, etc., выбор был остановлен на языке Python.

Этот язык не очень известен в России, но на Западе в настоящее время получает все большее распространение. Это происходит именно из-за его способности удовлетворить большинству предъявляемых к таким языкам требований. Даже таким противоречивым, как высокоуровневость с одной стороны, гибкость с другой и скорость работы с третьей. В итоге, с некоторыми небольшими оговорками он удовлетворил всем нашим требованиям.

Дополнительные преимущества

Кроме удовлетворения основным требованиям, выбрав Python, мы получили еще несколько дополнительных возможностей:

  1. Python можно скомпилировать в байт-код Java. Это дает возможность использования его для программирования активных страниц на интернет-серверах.
  2. На Python'е можно легко реализовать COM-объект для использования его в MS Office.

Перспективы развития форматов XML-документов

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

Мы, понимая важность момента практического применения XML, раскрываем свою технологию и делимся своим опытом с широким кругом разработчиков. Мы надеемся, что эта статья, а также другие материалы, которые мы собираемся представить на тему практического применения XML, будут способствовать развитию технологий взаимодействия бизнес-приложений в России. Автор статьи с удовольствием ответит на любые вопросы по предложенной технологии, отправленные по адресу Andreev@iso.ru.

Приложение. Примеры форматов XML-документов

Платежный документ

<Документы Количество="1">
   <Документ Тип="Плат_док" Номер="23">
      <Дата> 5-01-1999</Дата>
      <Валюта>810</Валюта>
      <ШтатнаяЕдиница>1_3</ШтатнаяЕдиница>
      <Субъект>1_1</Субъект>
      <Форма>Мем_орд</Форма>
      <СуммаДокумента>19521.00</СуммаДокумента>
      <Счет_пл>20202810906200100000</Счет_пл>
      <Счет_пол>40702810706200000055</Счет_пол>
      <Ном_пачки>106</Ном_пачки>
      <Назв_пл>БАНК 3333</Назв_пл>
      <Назв_пол>ЗАО "РЕЧТОРГ"</Назв_пол>
      <Осн>ПРИНЯТО ПО ОБЬЯВЛЕНИЮ НА ВЗНОС НАЛИЧНЫМИ</Осн>
      <ОКПО_пл>245003418</ОКПО_пл>
      <ОКПО_пол>276049043</ОКПО_пол>
      <БИК_пл>3333</БИК_пл>
      <БИК_пол>3333</БИК_пол>
      <Корр_сч_пл>111111111</Корр_сч_пл>
      <Корр_сч_по>111111111</Корр_сч_по>
      <Банк_пл>БАНК N 3333</Банк_пл>
      <Банк_пол>БАНК N 3333</Банк_пол>
      <Очер>6</Очер>
      <Срок_пл> 5-01-1999</Срок_пл>
      <ДополнительныеПараметры></ДополнительныеПараметры>
      <Срок_отпр> 5-01-1999</Срок_отпр>
      <Проводки>
         <Проводка>
            <Филиал>1</Филиал>
            <Дата> 5-01-1999</Дата>
            <СчетДебета>20202810906200100000/810_А</СчетДебета>
            <СчетКредита>40702810706200000055/810_А</СчетКредита>
            <Сумма>19521.00</Сумма>
            <ЗаключительныеОбороты>N</ЗаключительныеОбороты>
         </Проводка>
         <Проводка>
            <Филиал>1</Филиал>
            <Дата> 5-01-1999</Дата>
            <СчетДебета>Бал_симв_кс</СчетДебета>
            <СчетКредита>02_кс</СчетКредита>
            <Сумма>19521.00</Сумма>
         </Проводка>
      </Проводки>
   </Документ>
</Документы>

Подобным образом сформированы форматы для таких документов, как:
  1. Заявка на покупку валюты
  2. Заявка на продажу валюты
  3. Заявка на выдачу наличных
  4. Заявка на ссуду
  5. Кредитный договор
  6. Депозитный договор
  7. Срочное обязательство
  8. Договор на расчетно-кассовое обслуживание

Лицевой счет

<ЛицевыеСчета Количество="1">
   <ЛицевойСчет Номер="10601810406200800000/810_А">
      <Филиал>1</Филиал>
      <Операционист>1_40</Операционист>
      <Клиент>1_1</Клиент>
      <Валюта>810</Валюта>
      <Операция>Неопр_опер</Операция>
      <Название>ПРИРОСТСТОИМОСТИКОНТОРСКОГООБОРУДОВАНИЯ</Название>
      <СимволОтчетности>0</СимволОтчетности>
      <БалансовыйСтатус>P</БалансовыйСтатус>
      <ДополнительныеПараметры></ДополнительныеПараметры>
      <ОперацииОткрытия Количество="1">
         <ОперацияОткрытия>
            <ДатаОткрытия>17-09-1998</ДатаОткрытия>
         </ОперацияОткрытия>       </ОперацииОткрытия>
      <ОтнесенияСчета Количество="1">
         <ОтнесениеСчета>
            <ПланСчетов>ЦБ_РФ_А</ПланСчетов>
            <СинтетическийСчет>10601_Р</СинтетическийСчет>
         </ОтнесениеСчета>
      </ОтнесенияСчета>
   </ЛицевойСчет>
</ЛицевыеСчета>

Клиент

<Субъекты Количество="1">
   <Субъект Тип="Предп_орг" Код="1_101">
      <Название>ИВАН ГРОЗНЫЙ 101</Название>
      <Примечание>ГОСУДАРЬ ИВАН ГРОЗНЫЙ 101</Примечание>
      <Полн_назв>ГОСУДАРЬ ИВАН ГРОЗНЫЙ 101</Полн_назв>
      <ИНН>101</ИНН>
      <Индекс>450080</Индекс>
      <Адрес>Проектируемый проезд, 101</Адрес>
      <Телефон>111-11-11</Телефон>
      <Резидент>Д</Резидент>
      <Форма_собс>ЧП</Форма_собс>
      <ВидДеят>Стр</ВидДеят>
      <ДатаСоздания>01-02-1970</ДатаСоздания>
      <Город>MSK</Город>
      <ОПФ>ПБОЮЛ</ОПФ>
      <Индекс>111111</Индекс>
      <Страна>RUS</Страна>
      <ГруппыОбъекта>
         <ГруппаОбъекта>
            <Код>Клиент</Код>
            <Вид_кл>Ю</Вид_кл>
         </ГруппаОбъекта>
      </ГруппыОбъекта>
   </Субъект>
</Субъекты>

Аналогичным образом сформированы форматы для таких субъектов экономической деятельности, как:
  1. Физические лица.
  2. Банки корреспонденты.

Заявка на получение выписки и сама выписка по счету

<ВыпискаПоСчету>
   <НомерСчета>40702810010000000001/810_А</НомерСчета>
   <ДатаС> 1-02-2000</ДатаС>
   <ДатаПо>29-02-2000</ДатаПо>
   <Операция Метод="get"/>
</ВыпискаПоСчету>

<ВыпискаПоСчету>
   <НомерСчета>40702810010000000001/810_А</НомерСчета>
   <Клиент>ИВАН ГРОЗНЫЙ 101</Клиент>
   <ДатаС> 1-02-2000</ДатаС>
   <ДатаПо> 29-02-2000</ДатаПо>
   <ВходящийОстаток>0.0</ВходящийОстаток>
   <Дебет>400.00</Дебет>
   <Кредит>10500.00</Кредит>
   <ИсходящийОстаток>10100.00</ИсходящийОстаток>
   <ПроводкиВыписки Количество="3">
      <ПроводкаВыписки>
         <Филиал>1</Филиал>
         <Дата> 1-02-2000</Дата>
         <СчетДебета>30102810010000000002/810_А</СчетДебета>
         <СчетКредита>40702810010000000001/810_А</СчетКредита>
         <Сумма>500.00</Сумма>
         <ЗаключительныеОбороты>N</ЗаключительныеОбороты>
      </ПроводкаВыписки>
      <ПроводкаВыписки>
         <Филиал>1</Филиал>
         <Дата> 2-02-2000</Дата>
         <СчетДебета>45205810000010000003/810_А</СчетДебета>
         <СчетКредита>40702810010000000001/810_А</СчетКредита>
         <Сумма>10000.00</Сумма>
         <ЗаключительныеОбороты>N</ЗаключительныеОбороты>
      </ПроводкаВыписки>
      <ПроводкаВыписки>
         <Филиал>1</Филиал>
         <Дата>26-02-2000</Дата>
         <СчетДебета>40702810010000000001/810_А</СчетДебета>
         <СчетКредита>20202810010000000002/810_А</СчетКредита>
         <Сумма>400.00</Сумма>
         <ЗаключительныеОбороты>N</ЗаключительныеОбороты>
      </ПроводкаВыписки>
   </ПроводкиВыписки>
</ВыпискаПоСчету>