Реализация клиентской части медицинского приложения с помощью Saxon-CE и HL7 CDA

Использование XSLT 2.0 в браузере для лучшего представления клинических документов

На конференции XML-2011 в Праге д-р Майкл Кей, главный разработчик парсера XSL/XQuery Saxon, представил Saxon-CE, клиентский парсер XSLT 2.0, который работает в Web-браузере с использованием JavaScript. В этой статье показано, как применять XSLT 2.0 и XSLT-CE для создания представления в простом медицинском приложении, которое работает с клиническими документами, составленными с применением стандарта Health Level 7 Clinical Document Architecture (HL7 CDA).

Пирс Майкл Холлотт, старший консультант, Sierra Systems

Пирс Майкл Холлотт (Piers Michael Hollott) работает в индустрии программного обеспечения 15 лет и специализируется в области Java-разработки, XML-технологий и функционального программирования. Участвовал в ряде проектов по разработке ПО с открытым кодом и в настоящее время является консультантом компании Sierra Systems.



13.09.2012

Используемые сокращения

  • CSS: Cascading stylesheet – каскадные таблицы стилей
  • DOM: Document Object Model - объектная модель документа
  • HTML: HyperText Markup Language - язык разметки гипертекста
  • URL: User Interface – интерфейс пользователя
  • XHTML: Extensible HTML - расширяемый HTML
  • XML: Extensible Markup Language – расширяемый язык разметки
  • XSL: Extensible Stylesheet Language - расширяемый язык таблиц стилей
  • XSLT: Extensible Stylesheet Language Transformation – XSL-преобразование

Стандарт Health Level 7 (HL7) Clinical Document Architecture (CDA) основан на той же версии 3 стандартной информационной модели HL7, которая используется для разработки взаимодействия систем обмена сообщениями HL7 v3. Но если система обмена сообщениями HL7 служит для отдельных взаимодействий в сфере здравоохранения (таких как запросы, ответы и уведомления), то документ HL7 CDA ― это единый, постоянный документ с описанием визита пациента, историей болезни и т.п. Чтобы документ был удобочитаемым для человека, каждая запись CDA в дополнение к машиночитаемому коду содержит текстовое описание, как показано в в листинге 1. Строго говоря, сообщения HL7 v3 предназначены для передачи по проводам (например, в рамках взаимодействия клиент-сервер или распределения данных сервер-сервер); документы HL7 CDA, так как они тоже рассчитаны на чтение человеком, могут передаваться и другими средствами, например, по электронной почте.

Листинг 1. Запись о медицинском наблюдении в стандарте CDA: аллергия на пенициллин
<component>
    <section>
        <code code="10155-0" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC"/>
        <title>Allergies and Adverse Reactions</title>
        <text>
            <list>
                <item>Penicillin - Hives</item>
            </list>
        </text>
        <entry>
            <observation classCode="OBS" moodCode="EVN">
                <code xsi:type="CD" code="247472004" codeSystem="2.16.840.1.113883.6.96" 
                    codeSystemName="SNOMED CT" displayName="Hives"/>
                <statusCode code="completed"/>
                <entryRelationship typeCode="MFST">
                    <observation classCode="OBS" moodCode="EVN">
                        <code xsi:type="CD" code="91936005" 
                            codeSystem="2.16.840.1.113883.6.96" 
                            codeSystemName="SNOMED CT" 
                            displayName="Allergy to penicillin"/>
                        <statusCode code="completed"/>
                    </observation>
                </entryRelationship>
            </observation>
        </entry>
    </section>
</component>

Парсер Saxon уже несколько лет поддерживает преобразования XSLT 2.0 на стороне сервера. Недавно на конференции XML-2011 в Праге автор оригинального парсера Saxon д-р Майкл Кей представил альфа-версию инструмента Saxon Client Edition (Saxon-CE), который позволяет выполнять преобразование XSLT 2.0 непосредственно в клиентских Web-приложениях (в браузере). Saxon-CE решает давнюю проблему обработки XSL на стороне клиента, работая в любом современном браузере: до сих пор поддержка XSL не была последовательно реализована в различных браузерах. В Saxon-CE эта проблема решается путем использования в качестве механизма времени выполнения JavaScript.

Кроме того, XSLT 2.0 предоставляет несколько функций, которые не поддерживаются в оригинальной спецификации XSLT 1.0, таких как поддержка множественных документов (multiple [results] documents) и строгая типизация. В Saxon-CE эти функции теперь поддерживаются на стороне клиента, и некоторые из них, как показано в этой статье, идеально подходят для использования в клиентских приложениях — в частности, для поддержки множественных документов.

Подготовка к работе

Для разработки приложения CDA Viewer, описанного в этой статье, я использовал Web-сервер Unite, который поставляется вместе с последней версией браузера Opera. На самом деле можно использовать любой сервер приложений. Я говорю лишь о том, как разработать представление для клиентского приложения, и не описываю способы хранения или распространения CDA-документов. Для проверки своего представления я просто опубликовал пример CDA как URL непосредственно через Web-сервер (иначе, можно сохранить его в базе XML, такой как IBM® DB2® pureXML). Аналогично, мои XSL-преобразования также можно опубликовать как URL.

Загрузка Saxon-CE

Альфа-версию Saxon-CE можно загрузить с сайта Saxonica (см. ссылку в разделе Ресурсы). На данный момент она не предназначена для производственных приложений; однако учитывая успех оригинального парсера Saxon, я не сомневаюсь в том, что и клиентская часть быстро станет отраслевым стандартом, особенно если получит положительные отзывы ранних пользователей.

К альфа-версии прилагаются всеобъемлющие примечания. Файлы JavaScript из разархивированной папки выпуска можно скопировать в свой сервер приложений, как любые другие сценарии .js. Загрузите также примеры приложений. Сценарий JavaScript состоит из одного файла .nocache.js и ряда отдельных файлов .js — для каждого из основных браузеров. Эти файлы содержат фактический код парсера; файл .nocache.js определяет браузер и вызывает соответствующий сценарий .js. Примеры приложений состоят из файла XSL-преобразования, некоторых XML-данных и HTML-файла, который для запуска преобразования вызывает сценарий JavaScript Saxon-CE. Я построил свое приложение CDA Viewer по той же схеме, но слой преобразования разбил на три файла (см. раздел Загрузки). На Web-сервере у меня выделена одна папка для каждого примера приложения и еще одна для приложения CDA.


Функции XSLT 2.0

В спецификацию XSLT 2.0 добавлены многие новые возможности — такие как определения функций, множественные документы, последовательности и временные деревья, строгая типизация и синтаксический анализ текста. В этой статье выделяется поддержка множественных документов. На стороне сервера использование множественных документов означает создание нескольких документов, чтобы можно было создать начальную XHTML-страницу, которая ссылается на несколько других страниц с результатами, сгенерированными сервером. В контексте преобразования на стороне сервера под использованием множественных документов подразумевается именно это: множество документов. Этот подход демонстрируется в листинге 2. При создании множественных документов на стороне клиента с помощью Saxon-CE генерируемый контент на самом деле предназначен для разных областей экрана клиентского приложения (как правило, элементов div HTML-страницы).

Листинг 2. Множественные документы (на сервере)
<xsl:for-each select="section">
    <xsl:result-document href="{@id}.html">
        <xsl:apply-templates select="." mode="html" />
    </xsl:result-document>
</xsl:for-each>

Преобразование медицинского документа

Я организовал свои XSL-преобразования в три файла (см. раздел Загрузка):

  • cda.xsl. содержит основные преобразования для отображения документа, читабельного для человека;
  • cda-machine-readable.xsl. содержит настраиваемый уровень, который в настоящее время отображает машиночитаемые детали документа в упорядоченном виде;
  • cda-dom-interaction.xsl. содержит шаблоны для обработки взаимодействия с моделями DOM HTML-страницы, такими как события click.

Кроме того имеется файл CSS и собственно HTML-страница.

Файл CSS довольно прост. HTML-страница тоже проста и содержит ряд элементов div для разных областей экрана CDA Viewer, каждую из которых можно позиционировать с помощью идентификатора в CSS. Мой план заключается в том, чтобы загрузить весь CDA и преобразовать его, а затем обеспечить интерактивный доступ посредством DOM, так чтобы получить элемент div, называемый div-cache, который я спрятал в нижней части экрана. Этот буфер содержит копию каждой из записей в стандарте CDA. Текст можно увидеть, прокрутив страницу вниз, или скрыть этот элемент, пометив его как style="visibility:hidden;inline:none".

Код, приведенный в листинге 3, запускает процесс преобразования. Как видите, теги <script> вызывают первый сценарий JavaScript Saxon-CE, а затем таблицу стилей XSL-преобразования в документ CDA.

Листинг 3. Вызов Saxon-CE из HTML-страницы
<script type="text/javascript" language="javascript" src="../Saxonce.nocache.js"></script>
<script type="application/xslt+xml" language="xslt2.0" src="cda.xsl" 
                      input="SampleCDADocument.xml"></script>

Отображение оглавления CDA Viewer

В листинге 3 основной процесс преобразования сначала создает упрощенный заголовок CDA Viewer, извлекая некоторую информацию из оболочки CDA. Здесь уже можно увидеть xsl:Result-document в действии. В листинге 4 обратите внимание на то, что на тег <div> указывает его идентификатор #creation. method="ixsl:replace-content" ― это принятая в Saxon-CE краткая форма выражения "заменить содержание в интерактивном XSL". Я приведу пример ниже, при добавлении контента. При работе непосредственно с CDA для каждой ссылки на элемент в стандарте CDA нужно использовать пространство имен hl7:. Позже я покажу, что при работе с шаблонами, которые относятся к модели DOM, это не обязательно. Процесс может быть сложным, и это одна из причин, почему я разделил свои шаблоны на несколько таблиц стилей XSL.

Листинг 4. Замена содержания XSL:result-document
<xsl:result-document href="#creation" method="ixsl:replace-content">
    <div>
        <xsl:value-of>
            <xsl:value-of select="hl7:ClinicalDocument/hl7:title"/>: 
            <xsl:value-of 
              select="hl7:ClinicalDocument/hl7:recordTarget/hl7:patientRole/hl7:patient"/>
        </xsl:value-of>
    </div>
</xsl:result-document>

В следующем фрагменте кода из того же XSL-файла (см. листинг 5) показано, как из разделов документа CDA генерируется оглавление для CDA Viewer. Как форматируется оглавление, видно на примерах прилагаемых файлов. Аналогичный подход используется для помещения в буфер записи медицинских данных из CDA. В обоих случаях при каждом применении шаблона результаты добавляются к существующему содержимому целевого элемента <div>.

Листинг 5. Добавление содержания XSL:result-document
<xsl:result-document href="#notes" method="ixsl:append-content">
    <xsl:apply-templates select="//hl7:component/hl7:section" mode="notes"/>
</xsl:result-document>

<xsl:result-document href="#div-cache" method="ixsl:append-content">
    <xsl:apply-templates select="//hl7:component/hl7:section" mode="cache"/>
</xsl:result-document>

CDA Viewer с оглавлением показан на рисунке 1.

Рисунок 1. Оглавление CDA Viewer
Оглавление приложения CDA View

Взаимодействие с DOM

Сгенерированные идентификаторы используются для связи ссылок в оглавлении с записями CDA из буфера. Фрагмент шаблона, который использовался для создания записи оглавления, приведен в листинге 6 .

Листинг 6. Связь с записью CDA в буфере
<a class="notes-section">
    <xsl:attribute name="id"><xsl:value-of select="generate-id(.)"/></xsl:attribute>
    <xsl:value-of select="hl7:title"/>
</a>

В листинге 7 обратите внимание на то, как атрибут шаблона mode="ixsl:onclick" указывает Saxon-CE, что этот шаблон нужно применить для обработки события click. Это ничем не отличается от любого другого события click JavaScript: просто для обработки применяются Saxon-CE и таблица стилей XSL. Всякий раз, когда парсер обрабатывает событие click таким образом, контекст переходит от исходного XML-документа к DOM HTML-страницы, поэтому я и выделил эти шаблоны в таблицу стилей cda-dom-interaction.xsl. Сам шаблон отображает текст записи CDA, извлеченной из буфера, созданного ранее с помощью идентификатора, связанного с исходным событием click (идентификатор исходной anchor-ссылки). Этот текст заменяет содержимое элемента div результирующего документа note-detail. Затем шаблон применяет любые применимые последующие шаблоны для работы с машиночитаемым контентом записи CDA.

Листинг 7. Обработка события click из оглавления
<xsl:template match="a[@class='notes-section']" mode="ixsl:onclick">
    <xsl:variable name="div-id" select="@id"/>
    <xsl:variable name="selected-section" 
        select="//div[@id='div-cache']/div[@id=$div-id]/section"/>

    <xsl:result-document href="#note-detail" method="ixsl:replace-content">
        <h2><xsl:value-of select="$selected-section/title/text()"/> 
            (<xsl:value-of select="$div-id"/>)</h2>
        <div><xsl:value-of select="$selected-section/text"/></div>
        <h2>Machine-readable Content</h2>
        <xsl:apply-templates select="$selected-section" mode="mach-read">
            <xsl:with-param name="a" select="."/>
        </xsl:apply-templates>
    </xsl:result-document>
</xsl:template>

Чтобы разделить машиночитаемые детали и детали, воспринимаемые человеком, я создал и включил третью таблицу стилей преобразования cda-machine-readable.xsl. Разделение этих шаблонов имеет то преимущество, что эту третью таблицу стилей можно расширить или полностью заменить более сложной таблицей стилей для обработки машиночитаемой информации в CDA. Это может понадобиться, например, для предоставления более наглядных таблиц или графиков или для работы с записями определенного типа. Можно пойти еще дальше и загрузить другой XML-документ, возможно, из хранилища метаданных, и развернуть некоторые коды из машиночитаемых данных или классифицировать их с помощью общих кодовых систем. Сохранение шаблонов для преобразования машиночитаемых записей ― это хороший стиль программирования, как и разделение задач в целом. Такая практика необходима при работе с крупномасштабными преобразованиями или преобразованиями, которые предполагается наращивать.

Отображение машиночитаемых медицинских записей

В моей минималистской таблице стилей преобразования машиночитаемого документа имеется шаблон, который определяет количество известных типов записей (наблюдение, учет лекарств, процедура и заключение) и оформляет их с помощью маркированных списков и таблиц. Я не пытался сделать здесь что-то слишком изощренное, но этот пример наглядно показывает, сколь существенный вклад может внести простой шаблон в оформление и организацию данных. Обратите внимание также на то, как в листинге 8 исходная anchor-ссылка передается в шаблон с помощью параметра. Этот шаг не обязателен для отображения машиночитаемых данных; ссылка передается через этот шаблон и сохраняется в буфере для последующего использования в скрытом элементе div в нижней части расшифровки записи. Впоследствии информация этой ссылки будет применяться для построения того, что я называю pin-областью. Для краткости я опускаю в xsl:choose все, кроме xsl:when для записи типа "наблюдения" (Observation).

Листинг 8. Создание шаблона машиночитаемых записей CDA
<xsl:template match="section" mode="mach-read">
    <xsl:param name="a"/>

    <div id="mach-read">
        <xsl:choose>
            <xsl:when test="entry/observation">
                <h3>Observations</h3>
                <ul>
                    <xsl:for-each select="entry/observation">
                        <li><a>
                            <xsl:value-of select="text"/>
                            <xsl:value-of select="code/@displayName"/>
                            <xsl:for-each select="value">
                            (<xsl:value-of><xsl:value-of select="@value"/> 
                                <xsl:value-of select="@unit"/></xsl:value-of>)
                            </xsl:for-each>
                        </a></li>
                    </xsl:for-each>			
                </ul>
            </xsl:when>
            <xsl:otherwise>(no match)</xsl:otherwise>
        </xsl:choose>
        <div class="xref" style="visibility:hidden;inline:none">
            <xsl:copy-of select="$a"/>
        </div>
    </div>
</xsl:template>

Поскольку этот шаблон применяется к копии исходных данных CDA, содержащихся в буфере DOM, для таких элементов, как entry, code и observation, не требуется hl7:. Это пространство имен можно добавить к записям CDA из буфера, но в этом мало пользы, потому что никакой дальнейшей сериализации не выполняется. Это имело бы смысл, если бы между элементами HL7 CDA и другими элементами на странице возникала какая-либо двусмысленность.

На рисунке 2 показан CDA Viewer, отображающий событие наблюдения с изложением видов аллергии и неблагоприятных реакций.

Рисунок 2. События наблюдения, такие как аллергия и неблагоприятные реакции
События наблюдения, такие как аллергия и неблагоприятные реакции

Разработка нового шаблона: pin-область

Pin-область ― это шаблон, возникший в процессе разработки этих преобразований под влиянием способа реализации результирующих документов XSLT 2.0 в Saxon-CE. Как описано выше, сгенерированный контент можно ввести в область экрана либо дополнительно, либо взамен уже существующего. Как правило, требуется заменить существующий контент; однако при повторном применении шаблона его нужно будет добавлять. Если к одной и той же области экрана применяется несколько шаблонов, можно создать коллекцию, напоминающую закладку: со временем ее можно интерактивно наращивать без удаления какого-либо контента из области экрана.

Взгляните на шаблон прикрепляющих ссылок в примере кода, приведенном в листинге 9. Конечно, это лишь пример приложения, но идея впечатляет. При нажатии на ссылку в оглавлении приложения Viewer производится обработка события click и отображается содержимое соответствующего раздела CDA. Однако при нажатии на любую другую ссылку простой anchor-шаблон обрабатывает событие и копирует содержимое ссылки в pin-область. Таким образом, Viewer можно использовать для просмотра содержания медицинского документа и "прикрепления" записей на будущее.

Листинг 9. Шаблон pin-области
<xsl:template match="a" mode="ixsl:onclick">
    <xsl:variable name="div-mach-read" select="ancestor::div[@id='mach-read']"/>
    <xsl:result-document href="#pin" method="ixsl:append-content">
        <div>
            <xsl:attribute name="title"><xsl:value-of select="$div-mach-read/h3"/> 
            - <xsl:value-of select="text()"/></xsl:attribute>
            <xsl:copy-of select="$div-mach-read/div[@class='xref']/a"/> -
            <xsl:value-of select="text()"/>
        </div>
    </xsl:result-document>
</xsl:template>

Рисунок 3 иллюстрирует использование pin-области.

Рисунок 3. Pin-область CDA Viewer
Pin-область CDA Viewer

Конечно, преимущества этого шаблона возрастут, если с прикрепленными записями удастся сделать что-нибудь полезное; однако это выходит за рамки темы настоящей статьи. Например, это может быть плагин для браузера электронной почты, который позволяет пациенту просматривать документы CDA, полученные от своего лечащего врача, закрепляя некоторые записи и включая их в ответное сообщение. В силу своего декларативного подхода к обработке информации Saxon-CE и XSLT 2.0, без сомнения, станут полезными инструментами разработки таких приложений.


Заключение

CDA-документы ведутся длительное время и в результате часто становятся достаточно громоздкими. Хотя они предназначены для чтения человеком, CDA-документы содержат и много машиночитаемой информации, которую можно сделать более управляемой, преобразуя ее в расширенное представление в клиентском приложении. Я убежден, что в будущие версии Saxon-CE войдет важный инструмент, предназначенный для этой цели, просто потому, что он может работать на любом современном браузере и поддерживает на стороне клиента такие возможности XSLT 2.0, как работа с множественными документами. Я не сомневаюсь, что эта технология станет незаменимой для разработчиков приложений в сфере здравоохранения.


Загрузка

ОписаниеИмяРазмер
Пример приложения CDAcda_sample.zip16 КБ

Ресурсы

Научиться

Получить продукты и технологии

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=XML
ArticleID=835192
ArticleTitle=Реализация клиентской части медицинского приложения с помощью Saxon-CE и HL7 CDA
publish-date=09132012