Blog de divulgación de Ciencia y Tecnología
How to

Convertir HL7 a XML con Mirth Connect

El estándar HL7 ha ido evolucionando a lo largo del tiempo en sus distintas versiones. Inicialmente la codificación en ER7 fue muy popular, pero la versión HL7 v2 incorporó la codificación en XML. Esto hace que en un mismo sistema, o en un mismo centro, puedan convivir ambos formatos, y sea necesario convertir mensajes HL7 a XML, y viceversa.

En este caso nos centraremos en la conversión de un mensaje de un sistema «mas moderno» que trabaja ya en HL7 v2.xml a un sistema que aún trabaja en «pipes».

Con Mirth Connect, es muy sencillo automatizar un cambio de codificación HL7 a XML utilizando la opción del Strict Parser, que utiliza los esquemas oficiales de la librería HAPI.

Veremos un caso práctico simulado con Mirth Connect para conseguir la interoperabilidad entre dos sistemas que necesitan esta conversión para entenderse.

Caso práctico: Convertir una petición HL7 de Banco de Sangre a XML

El HIS de un hospital aún está utilizando mensajería HL7 en formato ER7 (texto plano con pipes) con el resto de sistemas. Recientemente se ha implantado un nuevo sistema de gestión del banco de sangre, que sólo trabaja ya con HL7 v2.xml sobre HTTP.

A pesar de haber adaptado ya las peticiones del antiguo sistema, que se comunicaba a través de tablas de base de datos, necesitamos hacer una conversión de HL7 ER7 a HL7 v2.xml.

Como no se quiere tocar el desarrollo existente, se desea incluir un wrapper que transforme el mensaje de las tablas de salida, a un XML que se envíe por HTTP.

Esquema de la conversión HL7 a XML
Arquitectura de la conversión HL7 a XML

La versión de HL7 es 2.5, tanto en el nuevo sistema de banco de sangre como en el HIS. Por tanto, tampoco sólo habrá que convertir:

  • Interfaz de base de datos a HTTP
  • Codificación de HL7 ER7 a XML.

Strict Parser en Mirth Connect

El flujo de datos de Mirth Connect realiza serialización y des-serialización de los mensajes para facilitar el trabajo con los datos, como XML. Sin embargo, el Serializer en Mirth no realiza un parseo a través (ni validando) los esquemas oficiales de HL7 por defecto, sino al manejo interno de datos.

Para nuestra facilidad, tenemos la posibilidad de activar un «parseo estricto» con el analizador de HAPI. Esta opción nos permite generar (o validar) el mensaje ajustado a la especificación oficial de HL7.

En nuestro caso, estaremos recogiendo un valor desde base de datos en una variable mapeada. Esto quiere decir que el mensaje HL7 no pasa directamente al flujo de datos serializado. Por tanto, mapearemos la cadena con el mensaje, y en un transformador de fuente, realizaremos la conversión.

Canal Mirth Convertir HL7 a XML

Siguiendo lo anterior, el canal que vamos a crear para hacer la conversión utilizará la función getSerializer() de la SerializerFactory. Activaremos la propiedad «Use Strict Parser» especificando en el destino que el tipo de datos será XML.

1. Creamos el canal ConvertirHL7aXML con los tipos de datos XML

En la opción Set Data Types de la pestaña Summary, especificamos XML para el Inbound y Outbound del Source Connector, tanto como del Destination. Esto es porque, la fuente va a ser una lectura de base de datos. Mirth va a convertir internamente cada registro que venga de base de datos en un xml mapeado.

Nosotros trabajaremos con XML, y obtendremos el campo del mensaje HL7 para realizar la conversión a HL7 v2.xml.

Por otro lado, el destino será un mensaje HL7 v2.xml por lo que se mantiene este formato XML en el flujo de datos de Mirth.

Data Types del canal
Data Types del canal

En todos ellos desmarcaremos Strip Namespaces, ya que esta opción la configuramos con el objeto serializationProperties en la invocación al método getSerializer().

2. Configurar Source Connector

En esta pestaña configuramos el Polling sobre la tabla de base de datos que contiene el mensaje en HL7 ER7. La lectura de esta tabla nos devolverá cada registro pendiente de envío, y lo tendremos en el mapping del flujo de datos, en XML.

Pestaña Source ConvertirHL7aXML
Pestaña Source ConvertirHL7aXML

3. Transformer de la pestaña Source

En la pestaña Source, nos vamos a los Transformadores y tenemos dos: Por un lado un mapping del mensaje HL7 recogido en base de datos a una variable. Por otro, un Javascript donde realizaremos la conversión de HL7 a XML.

Mapeo del mensaje en HL7 ER7

En la parte derecha podemos ver la serialización interna que ha hecho Mirth de cada registro obtenido de base de datos, donde tenemos un xml con los dos campos recogidos.

Nos interesa manejar como String el mensaje HL7 en ER7, por lo que mapeamos a la variable del mapa mensajeHL7, que usaremos en el siguiente paso.

Mapeo ConvertirHL7aXML
Mapeo ConvertirHL7aXML

Serialización a HL7 v2.xml

Añadimos un paso de tipo Javascript, donde vamos a recoger un objeto SerializationProperties con los siguientes valores:

  • convertLineBreaks : True; Esto convertirá los LF (salto de línea) en CR (Retorno de carro).
  • useStrictParser : True; Esto es lo que activará el parser según los esquemas oficiales para la conversión a HL7 v2.xml.
  • useStrictValidation: False; No vamos a realizar una validación del mensaje, solo un parseo y conversión.
  • stripNamespaces: False; Luego incluiremos nuestro namespace por defecto correspondiente al HL7 v2.xml.
  • handleSubcomponents: True; Vamos a parsear todo el mensaje, incluyendo subcomponentes. Esto no necesitaríamos activarlo, ya que al activar useStricParser ya lo hace, es sólo por reflejar lo que se está haciendo.
  • handleRepetitions: True; De la misma manera, teniendo activado useStricParser no es necesario, ya que parseará las repeticiones independientemente de este valor.

Después invocaremos al método toXML() del objeto serializado con getSerializer() del SerializerFactory, indicando la versión HL7V2. De esta manera el transformador quedará así:

//  Transformer Source para convertir en HL7 XML la lectura de un campo de BD donde se recoge HL7 ER7 
//
// Autor: Jose Ramón Pascual
// Artículo :  Convertir HL7 a XML con Mirth Connect
// Disponible en https://www.disrupciontecnologica.com/convertir-hl7-a-xml-con-mirth-connect/

var serializationProperties = SerializerFactory.getDefaultSerializationProperties('HL7V2');
serializationProperties.put('convertLineBreaks',true);
serializationProperties.put('useStrictParser',true);
serializationProperties.put('useStrictValidation',false);
serializationProperties.put('stripNamespaces',false);
serializationProperties.put('handleSubcomponents',true);
serializationProperties.put('handleRepetitions',true);

// Poner default namespace antes de usar el strict parser
default xml namespace = new Namespace('urn:hl7-org:v2xml');

tmp = SerializerFactory.getSerializer('HL7V2', serializationProperties, null).toXML( $('mensajeHL7') );

4. Configurar Destination

En la última línea de paso Javascript anterior estamos asignando el resultado del método getSerializer() al flujo de datos de salida tmp.

Esto nos permitirá trabajar en formato XML, como hacemos habitualmente, en los transformers de los destinos. De esta manera, teniendo ya convertido el mensaje en XML en el flujo de datos, nos permitiría hacer un mapeo de esta forma:

msg['MSH']['MSH.7']['TS.1'] = DateUtil.getCurrentDate('yyyyMMddhhmmss');

Si necesitásemos actualizar el TimeStamp del mensaje al actual para un destino concreto.

En resumen, tenemos en el flujo de datos de Mirth el mensaje leído desde base de datos en HL7 y ya convertido en HL7 v2.xml con los esquemas oficiales.

Como el destino del resultado de la conversión es un WebService HTTP Rest, configuraremos el conector destino hacia el mismo formato.

Destination del canal Convertir HL7 a XML
Destination del canal Convertir HL7 a XML

Como el Payload es XML, en Content Type hay que indicarlo, y como ya tenemos el mensaje convertido en el flujo de datos, enviaremos el valor de encodedData.

Tenemos listo el canal para probarlo con un mensaje:

5. Probando la conversión

Desplegamos nuestro canal, que realizará una lectura sobre la base de datos obteniendo un registro como el siguiente en la lectura RawData:

<result>
    <idmensaje>12345678</idmensaje>
    <mensajehl7>MSH|^~\&amp;|HIS|HOSPITAL|BBANK|EXTERNO|20190429090131||OMB^O27^OMB_O27|12345678|P|2.5|||AL|NE||8859/1
PID|1||21112222^^^HIS^PI^^^^2828&amp;&amp;~SHJD310801911024^^^MS^HC^^^^ESP&amp;&amp;ISO3166~1110001100^^^CA13^JHN^^^^CL&amp;&amp;ISO3166-2~22221111^^^MI^NNESP^^^^ESP&amp;&amp;ISO3166~22/00000001/01^^^SS^SS^^^^ESP&amp;&amp;ISO3166||LEE^SHELDON|COOPER|19800226|M|||CL&amp;ERNESTO GUEVARA&amp;202^CENTRO SALUD^28078^28^28048^ESP^H^MADRID~&amp;&amp;^^^^^ESP^M^||^PRN^PH^^^^^^^^^666112233
PV1|1|I|^^405C^||||666^OCHOA^SEVERO^DE ALBORNOZ^^^^|||MIN|||||||||12345^^^^^||||||||||||||||||||||||||||||||
SPM|1|11234556
ORC|NW|11234556|11111222||||||20190429090000|OCHOA, SEVERO|OCHOA, SEVERO|6145^OCHOA^SEVERO^DE ALBORNOZ||||||OCHOA, SEVERO
BPO|CHEM^Concentrado de Hematíes|2||2||20190428200001|P121^^^^||20190428211001|P121^^^^||||
BPO|PQ^Pool Plaquetas|1||1||201904281200001|P121^^^^||20190428211001|P121^^^^||||
</mensajehl7>
</result>

Y lo que tendremos en nuestra salida del Destination, será lo siguiente:

Resultado de convertir a XML y enviar a HTTP
Resultado de convertir a XML y enviar a HTTP

Con este mensaje completo ya convertido en XML y equivalente al original (que estaba en HL7 ER7).

<OMB_O27 xmlns="urn:hl7-org:v2xml">
    <MSH>
        <MSH.1>|</MSH.1>
        <MSH.2>^~\&amp;</MSH.2>
        <MSH.3>
            <HD.1>HIS</HD.1>
        </MSH.3>
        <MSH.4>
            <HD.1>HOSPITAL</HD.1>
        </MSH.4>
        <MSH.5>
            <HD.1>BBANK</HD.1>
        </MSH.5>
        <MSH.6>
            <HD.1>EXTERNO</HD.1>
        </MSH.6>
        <MSH.7>
            <TS.1>20190429090131</TS.1>
        </MSH.7>
        <MSH.9>
            <MSG.1>OMB</MSG.1>
            <MSG.2>O27</MSG.2>
            <MSG.3>OMB_O27</MSG.3>
        </MSH.9>
        <MSH.10>12345678</MSH.10>
        <MSH.11>
            <PT.1>P</PT.1>
        </MSH.11>
        <MSH.12>
            <VID.1>2.5</VID.1>
        </MSH.12>
        <MSH.15>AL</MSH.15>
        <MSH.16>NE</MSH.16>
        <MSH.18>8859/1</MSH.18>
    </MSH>
    <OMB_O27.PATIENT>
        <PID>
            <PID.1>1</PID.1>
            <PID.3>
                <CX.1>21112222</CX.1>
                <CX.4>
                    <HD.1>HIS</HD.1>
                </CX.4>
                <CX.5>PI</CX.5>
                <CX.9>
                    <CWE.1>2828</CWE.1>
                </CX.9>
            </PID.3>
            <PID.3>
                <CX.1>SHJD310801911024</CX.1>
                <CX.4>
                    <HD.1>MS</HD.1>
                </CX.4>
                <CX.5>HC</CX.5>
                <CX.9>
                    <CWE.1>ESP</CWE.1>
                    <CWE.3>ISO3166</CWE.3>
                </CX.9>
            </PID.3>
            <PID.3>
                <CX.1>1110001100</CX.1>
                <CX.4>
                    <HD.1>CA13</HD.1>
                </CX.4>
                <CX.5>JHN</CX.5>
                <CX.9>
                    <CWE.1>CL</CWE.1>
                    <CWE.3>ISO3166-2</CWE.3>
                </CX.9>
            </PID.3>
            <PID.3>
                <CX.1>22221111</CX.1>
                <CX.4>
                    <HD.1>MI</HD.1>
                </CX.4>
                <CX.5>NNESP</CX.5>
                <CX.9>
                    <CWE.1>ESP</CWE.1>
                    <CWE.3>ISO3166</CWE.3>
                </CX.9>
            </PID.3>
            <PID.3>
                <CX.1>22/00000001/01</CX.1>
                <CX.4>
                    <HD.1>SS</HD.1>
                </CX.4>
                <CX.5>SS</CX.5>
                <CX.9>
                    <CWE.1>ESP</CWE.1>
                    <CWE.3>ISO3166</CWE.3>
                </CX.9>
            </PID.3>
            <PID.5>
                <XPN.1>
                    <FN.1>LEE</FN.1>
                </XPN.1>
                <XPN.2>SHELDON</XPN.2>
            </PID.5>
            <PID.6>
                <XPN.1>
                    <FN.1>COOPER</FN.1>
                </XPN.1>
            </PID.6>
            <PID.7>
                <TS.1>19800226</TS.1>
            </PID.7>
            <PID.8>M</PID.8>
            <PID.11>
                <XAD.1>
                    <SAD.1>CL</SAD.1>
                    <SAD.2>ERNESTO GUEVARA</SAD.2>
                    <SAD.3>202</SAD.3>
                </XAD.1>
                <XAD.2>CENTRO SALUD</XAD.2>
                <XAD.3>28078</XAD.3>
                <XAD.4>28</XAD.4>
                <XAD.5>28048</XAD.5>
                <XAD.6>ESP</XAD.6>
                <XAD.7>H</XAD.7>
                <XAD.8>MADRID</XAD.8>
            </PID.11>
            <PID.11>
                <XAD.6>ESP</XAD.6>
                <XAD.7>M</XAD.7>
            </PID.11>
            <PID.13>
                <XTN.2>PRN</XTN.2>
                <XTN.3>PH</XTN.3>
                <XTN.12>666112233</XTN.12>
            </PID.13>
        </PID>
        <OMB_O27.PATIENT_VISIT>
            <PV1>
                <PV1.1>1</PV1.1>
                <PV1.2>I</PV1.2>
                <PV1.3>
                    <PL.3>405C</PL.3>
                </PV1.3>
                <PV1.7>
                    <XCN.1>666</XCN.1>
                    <XCN.2>
                        <FN.1>OCHOA</FN.1>
                    </XCN.2>
                    <XCN.3>SEVERO</XCN.3>
                    <XCN.4>DE ALBORNOZ</XCN.4>
                </PV1.7>
                <PV1.10>MIN</PV1.10>
                <PV1.19>
                    <CX.1>12345</CX.1>
                </PV1.19>
            </PV1>
        </OMB_O27.PATIENT_VISIT>
    </OMB_O27.PATIENT>
    <SPM>
        <SPM.1>1</SPM.1>
        <SPM.2>
            <EIP.1>
                <EI.1>11234556</EI.1>
            </EIP.1>
        </SPM.2>
    </SPM>
    <ORC>
        <ORC.1>NW</ORC.1>
        <ORC.2>
            <EI.1>11234556</EI.1>
        </ORC.2>
        <ORC.3>
            <EI.1>11111222</EI.1>
        </ORC.3>
        <ORC.9>
            <TS.1>20190429090000</TS.1>
        </ORC.9>
        <ORC.10>
            <XCN.1>OCHOA, SEVERO</XCN.1>
        </ORC.10>
        <ORC.11>
            <XCN.1>OCHOA, SEVERO</XCN.1>
        </ORC.11>
        <ORC.12>
            <XCN.1>6145</XCN.1>
            <XCN.2>
                <FN.1>OCHOA</FN.1>
            </XCN.2>
            <XCN.3>SEVERO</XCN.3>
            <XCN.4>DE ALBORNOZ</XCN.4>
        </ORC.12>
        <ORC.18>
            <CE.1>OCHOA, SEVERO</CE.1>
        </ORC.18>
    </ORC>
    <BPO>
        <BPO.1>CHEM</BPO.1>
        <BPO.2>
            <CWE.1>2</CWE.1>
        </BPO.2>
        <BPO.4>2</BPO.4>
        <BPO.6>
            <CE.1>20190428200001</CE.1>
        </BPO.6>
        <BPO.7>
            <TS.1>P121</TS.1>
        </BPO.7>
        <BPO.9>
            <XAD.1>
                <SAD.1>20190428211001</SAD.1>
            </XAD.1>
        </BPO.9>
        <BPO.10>
            <TS.1>P121</TS.1>
        </BPO.10>
    </BPO>
    <BPO>
        <BPO.1>PQ</BPO.1>
        <BPO.2>
            <CWE.1>1</CWE.1>
        </BPO.2>
        <BPO.4>1</BPO.4>
        <BPO.6>
            <CE.1>201904281200001</CE.1>
        </BPO.6>
        <BPO.7>
            <TS.1>P121</TS.1>
        </BPO.7>
        <BPO.9>
            <XAD.1>
                <SAD.1>20190428211001</SAD.1>
            </XAD.1>
        </BPO.9>
        <BPO.10>
            <TS.1>P121</TS.1>
        </BPO.10>
    </BPO>
</OMB_O27>

Conclusión

Con unos poco esfuerzo tenemos montado un wrapper de HL7 a XML en Mirth Connect. En el canal no hemos especificado en ningún momento qué tipo mensaje es el que vamos a recibir o enviar. Esto quiere decir que servirá de wrapper para convertir cualquier mensaje a formato HL7 (Pipes) a HL7 v2.xml con los esquemas oficiales.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Follow by Email
LinkedIn
Share
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de sus datos para estos propósitos. Ver
Privacidad