Обработка сообщения типа hl7 с помощью xslt, регулярного выражения или их комбинации (XSLT 1.0)

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

Формат этого сообщения: ДатаВремя(как ГГГГММДДЧЧММСС)^UnitName^room^bed|). Каждая локация отделена трубой, поэтому у каждого человека может быть одна или несколько локаций. И сообщения выглядят так (когда у пациента только одно местоположение):

20130602201605^Some Hospital^ABFG^411|

Конечный результат xml должен выглядеть так:

<Location>
 <item>
  <when>20130602201605</when>
  <UnitName>Some Hospital</UnitName>
  <room>ABFG</room>
  <bed>411</bed>
 </item>
</Location>

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

Итак, если у меня есть такое сообщение с несколькими местоположениями:

20130601003203^GBMC^XXYZ^110|20130602130600^Sanai^ABC^|20130602150003^John Hopkins^J615^A|

Конечный результат должен быть:

<Location>

 <item>
   <when>0130601003203</when>
   <UnitName>GBMC</UnitName>
   <room>XXYZ</room>
   <bed>110</bed>
 </item>

 <item>
  <when>20130602130600</when>
  <UnitName>Sanai</UnitName>
  <room>ABC</room>
  <bed></bed>
 </item>

 <item>
  <when>20130602150003</when>
  <UnitName>John Hopkins</UnitName>
  <room>J615</room>
  <bed>A</bed>
 </item>

</Location>

Итак, как бы я решил это? Заранее спасибо.


person Nick Jones    schedule 14.06.2013    source источник


Ответы (2)


Учитывая, что ваше сообщение Hl7 имеет кодировку "|^~\&", а не формат XML, неясно, как вы будете использовать процессор XSLT 1.0 для своей задачи. Можете ли вы более подробно описать свой конвейер обработки? Ваши фрагменты не являются полными сообщениями, и неясно, начнете ли вы с полных сообщений или попытаетесь проанализировать изолированные поля, переданные более крупной задаче обработки, с помощью параметров или чего-то еще.

Если ваша обработка начинается с полного сообщения HL7, я бы посоветовал изучить проект HAPI или аналогичный набор библиотек для преобразования сообщений из формата |^~\& в формат ‹/› с последующим вызовом XSLT для этой версии данных. (Вы также можете использовать библиотеки HAPI в решении, полностью основанном на Java. В любом случае примеры кода есть на сайте HAPI и в Сайт Apache на HL7.) Если вы вообще не заинтересованы в использовании Java, но открыты для частичных решений, отличных от XSLT, есть другие проекты, предоставляющие аналогичные варианты сериализации (например, Net::HL7 для Perl, nHAPI для VB/C# и т. д.).

Если вы изолировали закодированные данные "|^~\&" в файле, отформатированном иначе XML, я бы посоветовал изучить ссылку str:tokenize в функциях XSLT 1.0 exslt. (XSLT 2.0 имеет встроенную функцию токенизации.) Вы можете str:tokenize разделить данные по полям или разделителям компонентов, а затем создать элементы, используя токенизированные подстроки.

Вот таблица стилей

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:str="http://exslt.org/strings"
    extension-element-prefixes="str"
    version="1.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="data">
        <Location>
        <xsl:for-each select="str:tokenize(.,'|')">
            <xsl:call-template name="handle-field">
                <xsl:with-param name="field" select="."/>
            </xsl:call-template>
        </xsl:for-each>
        </Location>
    </xsl:template>

    <xsl:template name="handle-field">
        <xsl:param name="field"/>
        <xsl:variable name="components" select="str:tokenize($field,'^')"/>
        <item>
            <when><xsl:value-of select="$components[1]"/></when>
            <UnitName><xsl:value-of select="$components[2]"/></UnitName>
            <room><xsl:value-of select="$components[3]"/></room>
            <bed><xsl:value-of select="$components[4]"/></bed>
        </item>
    </xsl:template>

</xsl:stylesheet>

который проходит через этот ввод

<?xml version="1.0" encoding="UTF-8"?>
<data>20130601003203^GBMC^XXYZ^110|20130602130600^Sanai^ABC^|20130602150003^John Hopkins^J615^A|</data>

для создания этого вывода с помощью xsltproc:

<?xml version="1.0"?>
<Location>
  <item>
    <when>20130601003203</when>
    <UnitName>GBMC</UnitName>
    <room>XXYZ</room>
    <bed>110</bed>
  </item>
  <item>
    <when>20130602130600</when>
    <UnitName>Sanai</UnitName>
    <room>ABC</room>
    <bed/>
  </item>
  <item>
    <when>20130602150003</when>
    <UnitName>John Hopkins</UnitName>
    <room>J615</room>
    <bed>A</bed>
  </item>
</Location>
person Community    schedule 15.06.2013
comment
Извините, что так долго не отвечал, но забыл проверить. Я реализовал немного другой и более простой подход. Я использовал рекурсию, которая подсчитывает количество | (ограничители канала) и соответствующим образом зацикливает строку, используя отдельную функцию. Он работает нормально, но я думаю, что ваше решение, вероятно, намного надежнее. Спасибо, что научили меня использовать функцию токенизации. Живи и учись каждый день. - person Nick Jones; 09.01.2014

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

После того, как у вас есть отдельные элементы, вам нужно добавить их в свой XML как узлы.

person Sid    schedule 14.06.2013