Тестирование XSLT 2.0 для openEHR XML

Практический курс для новичков по тестированию XSLT-трансформаций openEHR XML. Вы освоите XPath 2.0, научитесь проверять наличие узлов, работать с cardinality и создавать unit-тесты для реальных openEHR-структур.

1. Основы XSLT 2.0 и XPath для тестирования

Основы XSLT 2.0 и XPath 2.0: фундамент для тестирования openEHR XML

XSLT (eXtensible Stylesheet Language Transformations) — это язык для преобразования XML-документов в другие форматы: другой XML, HTML, JSON, plain text. Версия 2.0 принципиально отличается от 1.0 поддержкой типов данных, группировки, множественных выходных документов и значительно расширенного набора функций XPath. Именно XSLT 2.0 используется в большинстве современных интеграционных решений на базе openEHR.

Представь XSLT как кулинарный рецепт: входной XML — это сырые ингредиенты, XSLT-таблица стилей — рецепт с инструкциями, а выходной документ — готовое блюдо. Тестирование XSLT — это проверка того, что рецепт всегда даёт правильный результат, даже если ингредиенты неполные или поданы в непривычном порядке.

Как устроен openEHR XML: структура, которую ты будешь трансформировать

Прежде чем писать трансформации и тесты, нужно понять, с каким XML ты работаешь. openEHR использует строго иерархическую модель данных, описанную в Reference Model (RM). XML-схемы для неё опубликованы в компоненте ITS-XML и включают XSD-схемы для RM, AM и BASE компонентов.

Центральный объект — Composition (клиническая запись). Внутри него находятся Section (разделы), которые содержат Entry (клинические записи: Observation, Evaluation, Instruction, Action). Каждый Entry содержит Element — конкретное значение с типом данных.

Ключевая особенность openEHR XML: каждый узел имеет атрибут archetype_node_id с at-кодом — уникальным идентификатором вида at0001, at0002 и т.д. Корневой элемент Composition или Entry дополнительно несёт атрибут archetype_id.

Обрати внимание: элемент items встречается дважды с разными archetype_node_id (at0004 и at0005). Это и есть кардинальность (cardinality) в действии — один и тот же тег-контейнер повторяется для разных клинических концептов. Это одна из главных сложностей при тестировании openEHR-трансформаций.

Анатомия XSLT 2.0 таблицы стилей

Минимальная рабочая XSLT 2.0 таблица стилей выглядит так:

Три ключевых элемента, которые нужно понять сразу:

  • xsl:template match="..."шаблон (template): правило, которое срабатывает, когда процессор встречает узел, соответствующий XPath-выражению в match
  • xsl:apply-templates — команда «обработай дочерние узлы, найди для них подходящие шаблоны»
  • xsl:value-of — вывести текстовое значение узла
  • Пространства имён — первый подводный камень при работе с openEHR XML. Все элементы openEHR находятся в пространстве имён http://schemas.openehr.org/v1. Если ты напишешь match="composition" без префикса ehr:, шаблон никогда не сработает — процессор просто не найдёт узел. Это самая частая ошибка новичков.

    XPath 2.0: язык навигации по XML-дереву

    XPath 2.0 — это язык запросов к XML-документу. Если XML — это дерево с ветками и листьями, то XPath — это адрес, по которому ты находишь нужную ветку или лист.

    Основные оси навигации

    | Ось | Что выбирает | Пример | |-----|-------------|--------| | child:: (или просто /) | Прямые дочерние узлы | ehr:composition/ehr:content | | descendant:: (или //) | Все потомки на любой глубине | //ehr:items | | attribute:: (или @) | Атрибуты узла | @archetype_node_id | | parent:: | Родительский узел | parent::ehr:data | | following-sibling:: | Следующие братские узлы | following-sibling::ehr:items |

    Предикаты: фильтрация узлов

    Предикат — это условие в квадратных скобках, которое фильтрует узлы. Именно предикаты делают XPath мощным инструментом для работы с openEHR:

    Функции XPath 2.0, критичные для тестирования

    В версии 2.0 появились функции, которых не было в 1.0 и которые особенно важны для тестирования:

    Шаблоны XSLT: match vs select

    Начинающие часто путают два атрибута — match и select. Разберём разницу на конкретном примере.

    match используется в xsl:template и описывает, какой узел активирует этот шаблон. Это как адрес на двери — шаблон «откликается», когда процессор приходит к нужному узлу.

    select используется в xsl:apply-templates, xsl:value-of, xsl:for-each и описывает, какие узлы обрабатывать или выводить прямо сейчас.

    При обработке нашего примера с артериальным давлением процессор последовательно встретит два узла items и для каждого найдёт свой шаблон по archetype_node_id. Результат:

    Режимы шаблонов: обработка одного узла по-разному

    Режим (mode) — механизм XSLT, позволяющий применить к одному и тому же узлу разные шаблоны в зависимости от контекста. Это особенно полезно в openEHR, где один и тот же архетип может нужен в разных частях выходного документа.

    Переменные и параметры в XSLT 2.0

    Переменная (xsl:variable) — именованное значение, которое вычисляется один раз и используется повторно. В отличие от большинства языков программирования, переменные в XSLT неизменяемы после объявления — это важный нюанс.

    Типы данных XPath 2.0 и openEHR

    XPath 2.0 — строго типизированный язык. Это означает, что сравнение "120" > "80" даст неожиданный результат (лексикографическое сравнение строк), а 120 > 80 — правильный (числовое). В openEHR XML все значения хранятся как текст, поэтому при тестировании числовых условий всегда используй явное приведение типов:

    Для дат openEHR использует формат ISO 8601 (2024-03-15T10:30:00). XPath 2.0 умеет работать с датами нативно:

    !Схема архитектуры XSLT 2.0 трансформации openEHR XML: входной документ, таблица стилей, процессор, выходной документ

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

    XSLT имеет встроенные шаблоны (built-in templates), которые срабатывают, если для узла не найдено явного шаблона. По умолчанию встроенный шаблон для элементов и корневого узла — рекурсивно применить шаблоны к дочерним узлам, а для текстовых узлов — вывести их содержимое.

    Это значит: если ты забыл написать шаблон для какого-то узла openEHR, его текстовое содержимое всё равно попадёт в выходной документ — просто без тегов. Такой «мусор» в выходном XML очень трудно заметить без тестов.

    Защита от этого — явный шаблон-заглушка:

    > Встроенные шаблоны XSLT — это «поведение по умолчанию», которое часто приводит к неожиданным результатам в продакшне. Явный шаблон-заглушка — обязательная практика в любой серьёзной трансформации openEHR.

    Понимание этих основ — фундамент для всего, что будет дальше: написания тестов на наличие и отсутствие узлов, проверки кардинальности и автоматизации тестирования openEHR-трансформаций. Каждая из этих тем строится именно на XPath-предикатах, шаблонах с match по archetype_node_id и корректной работе с пространствами имён.

    !Интерактивный XPath-навигатор по openEHR XML