Применение объектного отображения XML в обработке данных с повышенными требованиями к целостности

Бесплатный доступ

Рассмотрена роль схемы XML-документа и ее отображения на структуры данных программы в приложениях с повышенными требованиями к достоверности данных. Актуальность темы обусловлена широким применением XML как формата представления данных в задачах обмена электронными документами и распространенность XML Schema в задачах обеспечения форматно-логического контроля. Представлен оригинальный пакет для языка программирования Python, предназначенный для отображения схем документов XML на иерархию классов в приложении. Применение пакета в разработке программного обеспечения позволит существенно сократить повторяющийся код, связанный с сериализацией и десериализацией данных в XML-контейнерах, и, тем самым, повысить надежность и поддерживаемость кода в приложениях электронного документооборота. Результаты работы нашли практическое применение в разработках специализированного ПО для юридически значимого документооборота.

Еще

Объектно-ориентированный подход, объектное отображение документов

Короткий адрес: https://sciup.org/147155142

IDR: 147155142   |   DOI: 10.14529/ctcr160413

Текст краткого сообщения Применение объектного отображения XML в обработке данных с повышенными требованиями к целостности

Современные задачи обработки данных, такие как сдача налоговой отчетности в электронном виде, обмен юридически значимыми документами и др., имеют повышенные требования к достоверности информации и надежности алгоритмов ее обработки. Одна из важнейших процедур при проведении входного и выходного форматно-логического контроля обрабатываемых данных – проверка типов данных и верности структур, которые ими образованы. Применение XML как формата обмена данными и XML Schema для обеспечения контроля их целостности, зарекомендовало себя как проверенное и широко распространенное решение [1]. К преимуществам XML относятся высокая степень стандартизации, разнообразие программных компонентов для обработки, человеко-читаемый формат данных. Возможность создать и опубликовать схему XML-документа позволяет контролирующим органам формализовать обмен данными на уровне нормативных документов. Например, Федеральная налоговая служба России регламентирует оборот электронной налоговой и бухгалтерской отчетностью на веб-ресурсе [2], где можно ознакомиться с различными версиями схем документов для различных видов обмена данными. Таким образом, эффективная работа со схемой документа актуальна при разработке надежных систем обмена и обработки данных.

Взаимосвязь схемы документа и ее отображения на объектную модель данных

Исторически одной из самых первых идеологий работы с XML-документами является DOM (англ. Document object model) [3], в которой данные представляются в виде дерева из узлов XML различных типов, в частности текстовых блоков, элементов с атрибутами, комментариев и инструкций обработки. Этот подход предполагает последующее преобразование узлов дерева в экземпляры конкретных структур данных приложения и обратную операцию при сериализации этих структур в XML. Введение схемы документа в этот алгоритм предполагает проверку схемы при первоначальном построении дерева DOM, т. е. входной контроль целостности данных, однако, в ответственных приложениях необходим и выходной контроль при сериализации данных перед их передачей. Так как схема документа имеет конкретную структуру, специфическую для приложения, можно рассматривать внутренние структуры данных и схему документа, им соответствующую, во взаимосвязи. Для минимизации повторяющегося кода целесообразным представляется отталкиваться от схемы документа как при реализации считывания XML во внутренние объекты программы, так и при разработке кода для обратной операции. Для разработчиков на языке Python [4] авторами предлагается пакет для отображения объектной модели документов на иерархию классов Python, получивший название XML_ORM [5]. Пакет позволяет структурно проектировать схемы XML-документов, аналогично моделям таблиц БД фреймворка Django [6]. Объектно-ориентированный подход позволяет повторно использовать элементы схем путем наследования и переопределения полей XML-элементов. При задании класса-схемы автоматически генерируется код для загрузки и сохранения XML-документов, удовлетворяющих схеме. Также в составе пакета имеется класс-примесь, помещающий XML-контейнер внутрь архива Zip. Установка пакета производится из центрального репозитория пакетов для Python [7], с помощью менеджера пакетов Pip или из исходного кода, путем запуска в командной строке команды:

Рекомендуется предварительно создать и активировать виртуальное окружение с помощью пакета virtualenv или venv , если используется Python версии 3. Основным модулем пакета является модуль xml_orm.core , в котором объявлены классы для создания классов-отображений схем XML и для задания полей данных в документах.

Проектирование схем документов с помощью XML_ORM

Класс xml_orm.core.Schema аналогично классу django.db.models.Model [8] задает объектно-ориентированную модель XML-узла. Схема должна наследовать непосредственно класс Schema или один из его потомков. Множественное наследование схем на данный момент не разрешено, но число предков схемы, не относящихся к XML_ORM, а также глубина дерева наследования, не ограничены. Следующий пример определяет схему XML-узла с двумя простыми субэлементами ИД и ИмяФайла , которые будут транслированы в поля uid и name соответственно: from xml_orm.core import Schema from xml_orm.fields import *

class Document(Schema):

uid = SimpleField(u'ИД')

name = SimpleField(u'ИмяФайла')

class Meta:

root = u'Документ'

namespace = u''

Простые поля задаются с помощью классов SimpleField , BooleanField и др. Для них характерно отсутствие дочерних элементов и атрибутов. С такими полями связываются атомарные значения или списки атомарных значений. Параметры minOccurs и maxOccurs определяют, какой вид поле примет в составе объекта. Если поле имеет maxOccurs =1, то оно транслируется в обычное значение, причем, если задать minOccurs =0, то оно будет необязательным к заполнению. Поле с maxOccurs отличным от 1 (это значение не может быть равным 0), транслируется в список значений. При minOccurs =0 такой список по умолчанию инициализируется в пустое значение.

Класс Meta в составе схемы задает неизменные для всех подобных узлов параметры. В частности root задает имя элемента, а namespace – идентификатор пространства имен.

Простое поле может соответствовать как простому субэлементу XML-узла, так и его атрибуту. Его вид в XML-документе определяется наличием или отсутствием префикса @ в его имени. В следующем примере идентификатор документа из субэлемента преобразован в атрибут:

class NewDocument(Document):

uid = SimpleField(u'@ИД')

Схема NewDocument получена из исходной наследованием. При наследовании все поля схемы предка, имена которых совпадают с именами полей потомка, перекрываются. Новые поля добавляются в конец последовательности полей предка. Изменить позицию полей потомка в последовательности полей предка можно с помощью параметров insert_before и insert_after . В следующем примере поле uid перемещается в конец документа, а новое поле author добавляется в его начало.

class AnotherDocument(Document):

uid = SimpleField(u'ИД', insert_after='name')

author = SimpleField(u'Автор', insert_before='name')

Мета-информация при наследовании копируется и, при совпадении имен, заменяется: class Article(Document):

class Meta:

root = u'Статья'

encoding = 'windows-1251'

Новые экземпляры объектов схемы создаются, как обычные объекты Python, вызовом конструктора. Конструктору можно передавать именованные параметры, которые будут записаны в одноименные поля объекта. Неинициализированные таким образом поля можно присвоить позже, как обычные поля объекта. В следующем примере создается экземпляр класса Article .

art = Article(uid=1, author=u'Лев Толстой', name=u'Война и мир')

Преобразование в XML

Также экземпляр схемы может быть преобразован в байтовую строку или в строку unicode. Для преобразования в строку можно использовать стандартные функции str() и repr() . К сформированному XML-документу добавляется декларация с кодировкой, которая берется из мета-параметра encoding . Его значение по умолчанию равно utf-8 . При отсутствии нужных полей, преобразование в строку поднимает исключение SerializationError , поэтому желательно заключать его в блоки try-except или with , например: from xml_orm.core import SerializationError

try:

print str(art)

except SerializatonError as err:

print err

Также экземпляр может быть преобразован в строку unicode с помощью стандартной функции unicode() . При этом декларация к строке не добавляется.

Загрузка из файла

Новый экземпляр класса Schema можно создать путем загрузки из строки, файла или файлоподобного объекта, содержащих данные XML. Для этого служит универсальный метод класса load() , принимающий в качестве параметра строку или произвольный объект, обладающий методом read() . В следующем примере создаются три новых объекта Article из трех разных объектов. Предполагается, что на диске присутствует файл data.xml . fn = 'data.xml' fp = open(fn) st = open(fn).read()

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

Сохранение в файл

Потомки класса Schema могут переопределять метод save() , который по умолчанию ничего не делает. Класс реализует протокол менеджера контекстов, что позволяет использовать оператор with . При выходе из контекста автоматически вызывается метод save() . В следующем фрагменте, класс потомок Article добавляет простейшую функциональность сохранения данных в файл.

class SavedArticle(Article):

def save(self):

fn = geattr(self, 'xmlfile', None) if fn:

open(fn, 'w').write(str(self))

with SavedArticle() as art:

  • # при выходе из блока файл 'article.xml' будет сохранен

Выводы

Применение объектного отображения документов, предлагаемого пакетом xml_orm , позволяет отказаться от большого количества повторяющегося кода, связанного с загрузкой, сохранением и проверкой целостности типизированных документов. Это положительно сказывается на надежности и поддерживаемости кода, что особо важно в ответственных приложениях, зависящих от периодически изменяющейся нормативной базы. Переход на xml_orm позволяет разработчикам на Python, использующим XML, сосредоточиться на обрабатываемых данных и их структуре, что положительно сказывается на времени выхода приложений в релиз. Пакет успешно применяется при разработке приложений, обрабатывающих XML, как в open-source сообществе, так и в коммерческих приложениях. В частности, пакет играет ключевую роль в реализации шлюза межоператорского документооборота [9] в ЗАО Калуга Астрал. Дальнейшее развитие пакета xml_orm авторы видят в более тесной интеграции с различными СУБД, с целью обеспечения прозрачного цикла приема, контроля и сохранения документов в базе.

Список литературы Применение объектного отображения XML в обработке данных с повышенными требованиями к целостности

  • Extensible Markup Language (XML). Официальный сайт консорциума w3. -http://www.w3.org/XML/
  • Справочник налоговой и бухгалтерской отчетности. ФНС России. -http://format.nalog.ru/
  • Document Object Model (DOM). -http://www.w3.org/DOM/
  • Python software foundation. Официальный сайт. -https://www.python.org/
  • Официальный сайт проекта Django. -https://www.djangoproject.com/
  • Репозиторий пакетов для Python. Пакет xml_orm. -https://pypi.python.org/pypi/xml_orm
  • Django ORM. Официальная документация. -https://docs.djangoproject.com/en/dev/topics/db/models/
  • Пакет Etree. Страница документации. -https://docs.python.org/2/library/xml.etree.elementtree.html
  • Технология обмена юридически значимыми электронными документами между операторами электронного документооборота. НП РОСЭУ. Роуминг. -http://www.roseu.org/roaming/
Краткое сообщение