Март 2021 — Блог Александра Тихомирова

Жизненная ситуация

Часто встречается необоснованное злоупотребление перечисляемыми типами. И вообще в целом в ИТ, и в частности в xsd-схемах. Бывает, что "ноги растут" со стороны разработчиков, у которых используется "хардкод", но бывает, что и сами аналитики создают проблемную ситуацию, совершенно невынужденную.

Сразу оговорюсь, в данном посте буду иметь в виду ситуацию только относительно xsd-схем. Может когда-нибудь попозже попробую экстраполировать вопрос в общем на системы.

Проблематика

Проблема при злоупотреблении перечисляемыми типами в xsd-схемах простая. При изменении состава значений типа возникает необходимость изменять сам перечисляемый тип. Следовательно возникает необходимость менять версию схемы. А если сам процесс перерегистрации схемы и доработки систем под это изменение очень продолжительный (например, он продолжительный в СМЭВ), то эта ситуация может создать очень серьезные проблемы, вплоть до остановки бизнеса.

Решение

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

Гораздо гибче решение обмениваться кодами значений справочника. Сами значения справочника включить в регламент обмена. При каждом изменении значений справочника менять регламент. При этом нет необходимости менять сами xsd-схемы, системы будут продолжать обмен.

Помимо этого смело использовать перечисляемые типы можно для системных вещей. Например, для действий с записью можно смело ограничить значения на "создание", "обновление", "удаление" и т.п. Например:


<xsd:simpleType name="operationType">
   <xsd:restriction base="string">
      <xsd:enumeration value="CREATE">
         <xsd:annotation>
            <xsd:documentation xml:lang="ru">Добавление записи</xsd:documentation>
         </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="UPDATE">
         <xsd:annotation>
            <xsd:documentation xml:lang="ru">Обновление записи</xsd:documentation>
         </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="DELETE">
         <xsd:annotation>
            <xsd:documentation xml:lang="ru">Удаление записи</xsd:documentation>
         </xsd:annotation>
      </xsd:enumeration>
   </xsd:restriction>
</xsd:simpleType>

Лирика

Нельзя использовать перечисляемый тип, если значения регламентируются законодательством. Пусть это даже, например, гендерный пол человека. Никто не может с уверенностью дать гарантию, что через несколько лет даже в нашей стране не появятся новые значения пола, например, "онЖеБаба" или "онаЖеМужик". Есть страны, у которых это целый классификатор. Надеюсь, в нашей стране не дойдет до такого.

Но тем не менее в схеме базовых типах СМЭВ сейчас числится такой тип для пола:


<xs:simpleType name="GenderType">
   <xs:annotation>
      <xs:documentation>Пол.</xs:documentation>
   </xs:annotation>
   <xs:restriction base="xs:string">
      <xs:enumeration value="Male"/>
      <xs:enumeration value="Female"/>
   </xs:restriction>
</xs:simpleType>

Другой неправильный пример использования перечисляемого типа это тип boolean со значениями true / false. Понятно же всем, что в России это не работает :) в России полный fuzzy logic, и не факт что хватит третьего значения "Не знаю" ;)

Жизненная ситуация

Повидав немало xsd-схем, я обнаружил, что мало кто использует ограничения на типы даты / времени. Бывает все в схеме по максимуму ограничат, даже больше, чем нужно, а дата и время в используется исходном базовом типе.

Проблематика

Какие в такой ситуации я вижу риски при интеграции систем посредством обмена данными через XML-фалйы:

  • Пропуск при валидации по схеме "дефолтного" значения даты

    Дело в том, что в некоторых базах данных в полях с типом даты и даты / времени вместо значения null (пустого значения используется какое-нибудь минимальное значение, типо 1900-01-01.

    Что это значит.

    А то что при передаче данных по xsd-схеме дата, например, является обязательной, а в интегрируемой системе не реализовано ее корректного заполнения, и система заполнит ее "пустым" значением, например, тем же 1900-01-01. Передаст совсем не бизнесовую дату, которая сломает далее по процессу всю логику

  • Использование неправильного значения времени и даже даты из-за часовых поясов

    Мало кто заморачивается указанием часовых поясов в типах даты / времени xml-файлов, а это может привести к ошибкам, даже если при обмене оба сервера находятся в одном часовом поясе. Просто потому что при развертывании сервера забыли указать для него правильный часовой пояс, и он использует время Гринвича.

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

Решение

У этих описанных выше двух рисков есть одно простое покрытие: использование паттерна ограничения значений.

Ниже приведены примеры такого ограничения. Диапазон значения дат можно менять по вкусу, но с учетом "дефолтного" значения даты в используемой интегрируемой системой базе данных

  • Тип времени и даты


    <xsd:simpleType name="typeTimeStamp">
       <xsd:restriction base="xsd:dateTime">
          <xsd:pattern value="2[0-9][0-9][0-9]-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])T[0-2][0-9]:[0-5][0-9]:[0-5][0-9](\+(0[2-9]|1[0-2]):00|Z)"/>
       </xsd:restriction>
    </xsd:simpleType>
    Данный паттерн обязывает для времени либо явно указать часовой пояс, либо передать приведенное к Гринвичу время
  • Тип даты


    <xsd:simpleType name="typeDate">
       <xsd:restriction base="xsd:date">
          <xsd:pattern value="2[0-9][0-9][0-9]-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])"/>
       </xsd:restriction>
    </xsd:simpleType>

Лирика

В примере выше диапазон дат ограничен третьим тысячелетием. Если вы считаете, что ваша схема будет использоваться и в четвертом тысячелетии, то пример выше можно легко поправить с учетом этого :)

Но вообще лучше подстраховаться и значения годов четвертого тысячелетия не обрубать валидацией, да :) чтобы российский, например, госчиновник следующей цивилизации четвертого тысячелетия, откопав такую схему, не рассердился на человека 21-го века и не отправил в прошлое андроида при исполнении показывать кто тут валидный :)

В жизни каждого человека рано или поздно возникает необходимость сравнения двух версий текстовых файлов. Не только в жизни веб-программиста :)

Для этой цели использовать функциональность сравнения Microsoft Word смысла нет, да и не каждый имеет установленным это ПО и не каждый доверит ему сравнение двух текстовых файлов.

Поскольку мой основной инструмент работы с различными текстовыми файлами (xsd, xml, json, php, tpl и многие другие) это Notepad Plus Plus, то я нашел способ делать сравнение в нем. Я только нашел :) респект ребятам, которые это реализовали в свободном доступе.

Способ простой:

  1. Устанавливаете Notepad Plus Plus
  2. Устанавливаете в нем плагин Compare
  3. Открываете в Notepad Plus Plus оба файла
  4. Нажимаете на подпункт меню Compare в меню плагинов

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

Еще один совет: если при поиске плагина по названию compare вы его не видите, значит (скорее всего) у вас старая версия Notepad Plus Plus - ее просто нужно обновить

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

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

Кроме того, буду рад замечаниям и отзывам, постараюсь ответить на интересующие вас вопросы, попробую решить присланные вами задачки.

Помимо всего я готов на условиях дополнительной временной занятости (freelance) решать более серьезные задачи. Имею большой опыт в системной аналитике, в том числе серьезные государственные федеральные проекты (СМЭВ, ЕПГУ - то, чем я занимаюсь).

Мой контакт в телеграмме: @farlander