HL7

HL7 v2

HL7
Logotipo de HL7®

HL7 v2 es el estándar de intercambio de datos en sanidad mas conocido y utilizado del mundo. Se conoce comúnmente como «mensajería HL7» por cualquier profesional de sistemas en sanidad. Esto es así porque se basa en el intercambio de mensajes de estructura definida.

HL7 v1 Surge en 1987 como respuesta a una necesidad de establecer un estándar basado en ASTM para el intercambio de información en sanidad entre varios proveedores. Esta versión no tuvo demasiado éxito como estándar, básicamente fueron modificaciones mas restrictivas del propio ASTM.

La segunda versión, que se desarrolló en 1990 sí consiguió convertirse en un estándar ampliamente aceptado en el mundo de las TIC para salud. Ha llegado a generar toda una familia de estándares denominados HL7 v.2x. Desde entonces ha ido evolucionando hasta la versión mas actual, HL7 v.2.8, y ya se está trabajando en la versión HL7 v.2.9.

Aunque la organización HL7 Internacional ha desarrollado otros estándares de interoperabilidad en salud mas modernos, como HL7 v3, aún en la actualidad la versión HL7 v2 sigue siendo la más utilizada en el mundo de las TIC en sanidad.

Se podría decir que HL7 v2 ha supuesto en la década de los 90, y la siguiente, una disrupción tecnológica en el ámbito de las TIC en sanidad. En poco tiempo cualquier proveedor que no estuviese adaptado a este estándar, quedaba relegado a la obsolescencia.

¿Qué y cómo son los mensajes HL7 v2?

Se podría definir un mensaje HL7 como la unidad atómica de datos transferidos entre dos sistemas. Es una unidad atómica, pero consta de una estructura jerárquica de elementos ordenados en una secuencia concreta que lo componen.

HL7 v2 define los mensajes utilizando una notación abstracta. A partir de esta definición abstracta se pueden generar mensajes utilizando las reglas para la construcción de mensajes definidas en las guías del marco de trabajo de HL7.

Un mensaje HL7 se puede describir como una estructura jerárquica de elementos, asociada a un evento disparador que lo desencadena.

Estos elementos pueden ser grupos, segmentos, campos, componentes y subcomponentes, y cada uno tiene asociado una serie de atributos, como cardinalidad, obligatoriedad, tamaño y tipo de datos.

A partir de la especificación formal de un mensaje, se aplican las reglas de codificación que permitan construir mensajes HL7 para cada evento disparador de información.

Esta versión 2 del estándar define dos formas de codificar mensajes: ER7 y XML.

ER7

Encoding Rules Seven (ER7) es el sistema inicial de codificación de mensajería HL7, basado en el anterior formato ASTM utilizado para el intercambio de mensajería. Es el formato mas popular de codificación de mensajería HL7, y utiliza caracteres delimitadores para separar segmentos, campos, componentes y subcomponentes.

Un mensaje HL7 en ER7 tiene este peculiar aspecto:

MSH|^~\&|HIS|HOSPITAL|BBANK|EXTERNO|20190429090131||OMB^O27^OMB_O27|12345678|P|2.5|||AL|NE||8859/1
PID|1||21112222^^^HIS^PI^^^^2828&&~SHJD310801911024^^^MS^HC^^^^ESP&&ISO3166~1110001100^^^CA13^JHN^^^^CL&&ISO3166-2~22221111^^^MI^NNESP^^^^ESP&&ISO3166~22/00000001/01^^^SS^SS^^^^ESP&&ISO3166||LEE^SHELDON|COOPER|19800226|M|||CL&ERNESTO GUEVARA&202^CENTRO SALUD^28078^28^28048^ESP^H^MADRID~&&^^^^^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^^^^||||

A simple vista parece ininteligible, un grupo de líneas con muchos pipes. Este es uno de los motivos por los que posteriormente se empezó a usar XML, precisamente por ser mas legible que ER7.

Un mensaje HL7 en ER7 consiste en un conjunto de líneas de texto, donde cada línea representa un segmento (el separador de segmentos es precisamente el salto de línea CHR(13) o <cr>). Cada segmento empieza por un identificador de tres caracteres, y responde a un conjunto de datos de un contexto concreto.

Por ejemplo, un segmento PID (Patient Identification) incluirá una serie de campos del contexto de identificación de pacientes: Nombre, apellidos, DNI, NHC, fecha de nacimiento, etc.

Un segmento PV1 (Patient Visit Information) incluirá campos de información del contexto de un episodio: Número de episodio, tipo de episodio, fecha de ingreso, etc.

Cada segmento contiene una lista de campos, separados por el delimitador de campo, que corresponde al pipe «|». A su vez, cada campo puede ser un listado componentes separados por «^» y con capacidad de repetirse.

Enfoque bidimensional del mensaje

La forma de referirse a un campo concreto, o a una ubicación concreta de un mensaje, es de tipo matricial. Considerando el mensaje como una matriz bidimensional, donde las filas son los segmentos, y las columnas los campos, podríamos decir que la cuarta fila, el segmento SPM, tiene dos campos:

SPM-1 = "1"
SPM-2 = "11234556"

Si nos referimos a un campo que tiene componentes, como en nuestro ejemplo, en el segmento ORC campo 12, seguiremos la siguiente notación para referirnos a los componentes:

ORC-12.1 = "6145"
ORC-12.2 = "OCHOA"
ORC-12.3 = "SEVERO"

De esta forma, teniendo en cuenta que los segmentos finalizan con salto de línea, tenemos un enfoque bidimensional del procesamiento de un mensaje HL7 en ER7, como en la siguiente imagen.

Enfoque bidimensional de un mensaje HL7 en ER7
Enfoque bidimensional de un mensaje HL7 en ER7

Delimitadores ER7

Como comentaba anteriormente, el formato ER7 utiliza delimitadores para separar zonas de información, empezando por el contexto, como los segmentos, y en cada segmento, separadores de campos, componentes, etc.

Veamos todos los delimitadores que disponemos para generar un mensaje ER7:

DelimitadorDescripción
<cr>Final de segmento.
|Separador de campos.
^Separador de componentes.
&Separador de subcomponentes.
~ Delimitador de iteraciones en campos con repetición.
\Carácter de escapado.
#Carácter para patrón de truncado.

Cómo leer un mensaje ER7

Si observamos el mensaje de ejemplo, veremos que comienza con tres caracteres «MSH» que identifican el primer segmento de cada mensaje HL7, el segmento Message Header. En este segmento se va a incluir información relevante para el destinatario, como el tipo de mensaje, el tipo de codificación, versión de HL7, fecha y hora del mensaje, etc.

MSH|^~\&|HIS|HOSPITAL|BBANK|EXTERNO|20190429090131||OMB^O27^OMB_O27|12345678|P|2.5|||AL|NE||8859/1
PID|1||21112222^^^HIS^PI^^^^2828&&~SHJD310801911024^^^MS^HC^^^^ESP&&ISO3166~1110001100^^^CA13^JHN^^^^CL&&ISO3166-2~22221111^^^MI^NNESP^^^^ESP&&ISO3166~22/00000001/01^^^SS^SS^^^^ESP&&ISO3166||LEE^SHELDON|COOPER|19800226|M|||CL&ERNESTO GUEVARA&202^CENTRO SALUD^28078^28^28048^ESP^H^MADRID~&&^^^^^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^^^^||||

Este segmento se lee de una forma particular y diferente que el resto, porque el primer campo debe indicar el carácter delimitador de campo. En este caso, y ya es una convención, se usa el pipe «|».

Leer el segmento MSH
Leer el segmento MSH

Es decir, el campo MSH-1 (en amarillo) será «|». A partir de ahí seguiremos el contador de campos por cada delimitador pipe que encontremos.

Tenemos que el segundo campo, también en amarillo, tendrá el contenido:

MSH-2 = "^  ~  \ &"

Estos son los caracteres separadores de componente, repetición, escapado y subcomponente.

En teoría, un parseador tomará el valor de este campo MSH-1 para saber qué carácter utilizar para un explode de campos, y los del MSH-2 para un explode del resto de elementos. Siempre usará el <cr> para separar los segmentos.

Digo en teoría porque, por convención se usan siempre estos caracteres delimitadores, y ya no sería necesario realizar esta lectura.

Subrayado en verde tenemos un campo muy relevante para el receptor del mensaje, y que servirá para bifurcar su lógica de procesamiento, o filtrar. Se trata del campo MSH-9, y el valor que informa es el tipo de mensaje HL7.

Subrayado en azul tenemos el campo MSH-10, que informará el valor único del identificador global del mensaje. Se trata de un valor que servirá para identificar de forma unívoca al mensaje, no se puede repetir en otro.

Subrayado en rojo tenemos el campo MSH-12, que identificará la versión de HL7 en la que trabaja el mensaje enviado.

Si seguimos contando campos por cada pipe tendremos que los siguientes campos tienen los correspondientes valores:

CampoValorTipoLong.OptDescripción
MSH-1"|"ST1RSeparador de campo
MSH-2"^~\&"ST4RDelimitadores
MSH-3"HOSPITAL"HD180OSistema emisor del mensaje
MSH-5"EXTERNO"HD180OSistema destinatario del mensaje
MSH-7"20190429090131"TS26OFecha del mensje
MSH-9.1"OMB^O27"MSG7RTipo de mensaje
MSH-10"12345678"ST20RIdentificador único del mensaje
MSH-11"P"PT3REntorno: P = Producción
T = Pruebas
MSH-12"2.5"VID8RVersión HL7 del mensaje
MSH-15"AL"ID2OACK de confirmación de entrega
MSH-16"NE"ID2OACK de resultado de ejecución
MSH-18"8859/1"ID5OJuego de caracteres utilizado (ISO 8859/1)

Resto de segmentos distintos del MSH

Para el resto de segmentos de HL7 el modelo de lectura en dos dimensiones es idéntico, con la única salvedad que el primer campo empieza tras el primer pipe. Esto es así, y es lo que diferencia al segmento de cabecera MSH porque se debe definir el delimitador, y en otros segmentos esto ya está definido.

Por aclarar esto, en el ejemplo que nos ocupa, si vamos a procesar el segmento PV1, donde vendrán los datos de episodio del paciente:

PV1|1|I|^^405C^||||666^OCHOA^SEVERO^DE ALBORNOZ^^^^|||MIN|||||||||12345^^^^^||||||||||||||||||||||||||||||||

Tenemos que, el primer campo es el identificador del mensaje «PV1» a partir de ahí:

  • PV1-1 : Tiene el valor de secuencia = 1
  • PV1-2 : Tiene el valor del tipo de episodio, que está tabulado en una serie de valores (Tipo de dato IS que veremos mas adelante) con el valor «I» de «Ingreso».
  • PV1-3 : Este campo contiene la información de ubicación del paciente, y está compuesto por varios componentes:
    • PV1-3.1 : Unidad de enfermería con el valor vacío.
    • PV1-3.2 : Habitación, también sin valor.
    • PV1-3.3 : Cama de ingreso, con el valor «405C»
    • PV1-3.4 : Centro, y el valor está vacío.
  • … el resto de campos se procesan de manera similar…

XML

XML es un lenguaje de marcado parecido al HTML. Las siglas significan eXtensible Markup Language (Lenguaje de Marcado Extensible) y se trata de una especificación del W3C como lenguaje de marcado de propósito general.

XML ha significado un desarrollo considerable para la interoperabilidad, siendo el lenguaje favorito para ello en muchos sectores.

En el caso de HL7, aunque ya se venía cocinando desde tiempo atrás, en el año 2000 se decidió, en la reunión anual de HL7 en Dresden, que se consideraría la segunda codificación normativa. Esto sería a partir de la versión HL7 v2.3.1 y posterior v.2.4. Pero en dicha reunión se decidió que así sería también para las futuras versiones. Era algo inevitable, por las considerables ventajas que aporta XML, como por ejemplo, poder utilizar cualquier analizador XML para validar un mensaje HL7 v2.xml.

Reglas de codificación de mensajes

Las estructuras de mensajes HL7 v2.xml se representan como estructuras en XML, que contienen segmentos y campos también representados como elementos XML. Es decir, en un mensaje HL7 v2.xml tendremos etiquetas contenedoras para los segmentos, campos, componentes, etc. Por ejemplo, el segmento PID tendrá <PID> como nombre de elemento XML.

Los campos del segmento también tendrán su elemento XML. Por ejemplo, el campo 3 del segmento PID tendrá <PID.3> como nombre de elemento XML. Estos elementos XML de los campos de un segmento vendrán como hijos del elemento del segmento.

En la representación HL7 v2.xml se introduce un cambio respecto a la presentación del atributo del tipo de datos, que en el caso de los campos se especifica como atributo fijo en la lista de atributos. Sin embargo en los componentes se incluye en el modelo de contenido. Es decir, en un mensaje HL7 v2.xml tendremos etiquetas de tipo de datos para los componentes y subcomponentes.

Lo veremos con un ejemplo de mensaje HL7 de tipo ACK, respuesta de un mensaje previo, en formato ER7:

MSH|^~\&|HIS|HOSPITAL|BBANK|EXTERNO|20190429090131||ACK^^ACK|12345679|P|2.5
MSA|AR|123456
ERR|PID^1^16^103&Table value not found&HL70357

El equivalente a este mensaje, pero en formato HL7 v2.xml será el siguiente:

<ACK
    xmlns="urn:hl7-org:v2xml"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:hl7-org:v2xml ACK.xsd">
    <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>ACK</MSG.1>
            <MSG.3>ACK</MSG.3>
        </MSH.9>
            <MSH.10>12345679</MSH.10>
        <MSH.11>
            <PT.1>P</PT.1>
        </MSH.11>
        <MSH.12>
            <VID.1>2.5</VID.1>
        </MSH.12>
    </MSH>
    <MSA>
        <MSA.1>AR</MSA.1>
        <MSA.2>123456</MSA.2>
    </MSA>
    <ERR>
        <ERR.1>
        <ELD.1>PID</ELD.1>
        <ELD.2>1</ELD.2>
        <ELD.3>16</ELD.3>
        <ELD.4>
            <CE.1>103</CE.1>
            <CE.2>Table value not found</CE.2>
            <CE.3>HL70357</CE.3>
        </ELD.4>
        </ERR.1>
    </ERR>
</ACK>

Como podemos observar, tenemos etiquetado de los tipos de datos para los subcomponentes y los tipos compuestos. Por ejemplo, el campo MSH-7, de tipo TimeStamp:

		<MSH.7>
			<TS.1>20190429090131</TS.1>
		</MSH.7>

Así como en el caso del campo codificado CE del ERR-1.4

		<ELD.4>
			<CE.1>103</CE.1>
			<CE.2>Table value not found</CE.2>
			<CE.3>HL70357</CE.3>
		</ELD.4>

Estructura del mensaje

Desde la versión HL7 v.2.3.1 se estandarizó el uso de estructura de mensaje compartida por distintos eventos. Esto viene a ser que, dos eventos distintos utilicen una estructura de mensaje común, con los mismos segmentos y cardinalidad. Un ejemplo de esto es el mensaje ADT^A04, que puede utilizar la estructura ADT_A01.

Esto se representa en el componente MSH-9.3, de manera que, el caso comentado quedaría un campo MSH-9 = «ADT^A04^ADT_A01«.

Los esquemas v2.xml se basan en esta estructura de mensaje, de manera que el campo MSH-9 tiene 3 componentes:

MSH-9.1 = Message Type (En este caso sería ADT)
MSH-9.2 = Trigger Event (En este caso sería A04)
MSH-9.3 = Message Structure ID (En este caso sería ADT_A01)

Como dato de ejemplo, la estructura ADT_A01 la utilizan los eventos A01, A04, A05, A08, A13, A14, A28 y A31.

Esto significa que todos estos eventos generarán un mensaje con la misma estructura, en cuanto a secuencia y cardinalidad de segmentos.

En el formato HL7 v2.xml se representa la estructura del mensaje como el nodo raíz, y el resto de segmentos serán nodos hijos. El ejemplo de un mensaje ADT^A04 el nodo raíz sería:

<ADT_A01>
	<MSH>
		...
	</MSH>
	<EVN>
		...
	</EVN>
	<PID>
		...
	</PID>
	...
</ADT_A01>

Campos vacíos

Como hemos ido viendo, en la especificación v2.xml los campos individuales se representan por un elemento XML con un id de segmento de tres caracteres, con la posición que ocupan en él. Por ejemplo, el tercer campo del segmento PID se representará en el mensaje con la etiqueta <PID.3>.

En ER7 cuando un campo viene vacío, no lleva información, simplemente en su ubicación no hay nada. Al ser secuencial, procesamos los campos de forma ordenada, por ubicación. Es decir, si encontramos en el segmento PV1 algo así:

PV1||I|^^405C^|||||||CAR...

Sabremos que los campos PV1-3.1, PV1-3.2, PV1-4, PV1-5, etc. Están vacíos.

En la especificación v2.xml un campo vacío no necesita que se especifique su ubicación. Es decir, en v2.xml, un elemento sin contenido simplemente puede omitirse. No necesitaríamos incluir las etiquetas XML de dichos campos, quedando así:

<PV1>
                <PV1.2>I</PV1.2>
                <PV1.3>
                    <PL.3>405C</PL.3>
                </PV1.3>
 		<PV1.10>CAR</PV1.10>
</PV1>

Tipos de datos compuestos

Los tipos de datos básicos, o primitivas, no necesitan ninguna especificación de la estructura o tipo en el mensaje, sino que se incluye el valor directamente.

En el ejemplo anterior, el campo PV1.2 contiene el valor del tipo de episodio o paciente «Patient Class» y que está definido en el estándar como tipo de datos IS, longitud 1 y Requerido.

El tipo IS es un tipo primitivo tabulado, toma el valor de uno de los posibles valores definidos en una tabla (HL7 0004) definida por usuario. Por tanto al ser un tipo primitivo, y como comentábamos anteriormente, se incluye el valor, en este caso «I», directamente:

   <PV1.2>I</PV1.2>

En el caso de los tipos de datos compuestos, en la versión HL7 v2.xml se debe incluir la referencia a la estructura de datos como un elemento hijo XML. Además, al igual que cuando referimos a un campo, se debe incluir el índice ordinal dentro de la estructura.

Por ejemplo, tenemos este fragmento de un segmento PID del que tomamos el campo PID.3:

 <PID.3>
       <CX.1>12345</CX.1>
       <CX.4>
           <HD.1>XX</HD.1>
       </CX.4>
       <CX.5>PI</CX.5>
       <CX.9>
           <CWE.1>1111</CWE.1>
           <CWE.3>TABLA</CWE.3>
       </CX.9>
</PID.3> 

El estandar define el tipo de dato del campo PID.3 como CX (CX – extended composite ID with check digit) que se trata de un tipo compuesto. Es decir, tiene varios componentes.

Esta es la definición de componentes del PID.3:

<ID Number (ST)> ^ <heck Digit (ST)> ^ <Check Digit Scheme (ID)> ^ <Assigning
Authority (HD)> ^ <Identifier Type Code (ID)> ^ <Assigning Facility
(HD)> ^ <Effective Date (DT)> ^ <Expiration Date (DT)> ^ <Assigning Jurisdiction
(CWE)> ^ <Assigning Agency or Department (CWE)>

Como podemos observar, se incluye en cada componente un elemento XML con la referencia a la estructura y el ordinal que ocupa en ella. De esta manera, el primer elemento CX.1 es un tipo primitivo ST con el valor del identificador:

       <CX.1>12345</CX.1>

Se omiten los elementos del segundo y tercer componente, por llevar datos vacíos, se incluye el cuarto, que es de tipo compuesto HD (Hierarchic Designator) incluyendo el tipo y ordinal de estructura.

El elemento noveno correspondiente al componente Assigning Jurisdiction de tipo CWE (coded with exceptions) que es de tipo compuesto. Según el estándar es una estructura de 22 componentes, donde el primero es un identificador de tipo primitivo ST, y el tercero «Name of Coding System» de tipo ID también primitivo.

Al ser un tipo compuesto CWE se incluye la estructura de datos y el ordinal que ocupa el componente en la estructura:

       <CX.9>
           <CWE.1>1111</CWE.1>
           <CWE.3>TABLA</CWE.3>
       </CX.9>

Repetición de un segmento o campo

En HL7 v2.xml los grupos de repetición que tienen mas de un segmento tienen un trato distinto, puesto que llevan un nombre asociado al grupo de repetición.

Cuando en ER7 la repetición de grupos de segmentos se representa sin más, como la repetición de esos segmentos, en XML la repetición va encerrada en un elemento XML. Este elemento XML se incluye en las definiciones del esquema v2.xml.

Por ejemplo, si tenemos la siguiente definición de estructura de un mensaje tipo RDE O11 para la comunicación codificada de la prescripción farmacológica de un paciente:

MSH
[ { SFT } ]
[ { NTE } ]
	-- PATIENT begin
	[
		PID
		[ PD1 ]
		[ { NTE } ]
		-- PATIENT_VISIT begin
		[
			PV1
			[ PV2 ]
		]
		-- PATIENT_VISIT end
		-- INSURANCE begin
		[{
			IN1
			[ IN2 ]
			[ IN3 ]
		}]
		-- INSURANCE end
		[ GT1 ]
		[ { AL1 } ]
	]
	-- PATIENT end
	-- ORDER begin
	{
		ORC
		-- TIMING
		[{
			TQ1
			[ { TQ2 } ]
		}]
		-- TIMING begin
		-- ORDER_DETAIL begin
		[
			RXO
			[ { NTE } ]
			{ RXR }
			-- COMPONENT begin
			[{
			RXC
			[ { NTE } ]
			}]
			-- COMPONENT end
		]
		-- ORDER_DETAIL end
		RXE
		[ { NTE } ]
		-- TIMING_ENCODED begin
		{
			TQ1
			[ { TQ2 } ]
		}
		-- TIMING_ENCODED end
		{ RXR }
		[ { RXC } ]
		-- OBSERVATION begin
		[{
			OBX
			[ { NTE } ]
		}]
		-- OBSERVATION end
		[ { FT1 } ]
		[ BLG ]
		[ { CTI } ]
	}
	-- ORDER end

Podemos comprobar que el grupo ORDER admite repeticiones. Un grupo para cada prescripción farmacológica que tenga prescrito el paciente.

Un mensaje codificado para este tipo de órdenes en HL7 v2.xml, con tres prescripciones, tendría un aspecto parecido a este:

<RDE_O11>
    <MSH>
        ... campos del segmento MSH
    </MSH>
    <RDE_O11.PATIENT>
        <PID>
        ... campos del segmento MSH    
        </PID>
        <RDE_O11.PATIENT_VISIT>
            <PV1>
            ... campos del segmento PV1
            </PV1>
            <PV2>
            ... campos del segmento PV2
            </PV2>
        </RDE_O11.PATIENT_VISIT>
    </RDE_O11.PATIENT>
    <RDE_O11.ORDER> 
        <ORC>
        ... campos del segmento ORC de la primera orden
        </ORC>
        <RXE>
        ... campos del segmento RXE de la primera orden
        </RXE>
        <RDE_O11.TIMING_ENCODED>
            <TQ1>
            ... campos del segmento TQ1 de la primera orden
            </TQ1>
        </RDE_O11.TIMING_ENCODED>
        <RXR>
            ... campos del segmento RXR de la primera orden
        </RXR>
    </RDE_O11.ORDER>
    <RDE_O11.ORDER>
        <ORC>
        ... campos del segmento ORC de la segunda orden
        </ORC>
        <RXE>
        ... campos del segmento RXE de la segunda orden
        </RXE>
        <RDE_O11.TIMING_ENCODED>
            <TQ1>
            ... campos del segmento TQ1 de la segunda orden
            </TQ1>
        </RDE_O11.TIMING_ENCODED>
        <RXR>
            ... campos del segmento RXR de la segunda orden
        </RXR>
    </RDE_O11.ORDER>    <RDE_O11.ORDER>
        <ORC>
        ... campos del segmento ORC de la tercera orden
        </ORC>
        <RXE>
        ... campos del segmento RXE de la tercera orden
        </RXE>
        <RDE_O11.TIMING_ENCODED>
            <TQ1>
            ... campos del segmento TQ1 de la tercera orden
            </TQ1>
        </RDE_O11.TIMING_ENCODED>
        <RXR>
            ... campos del segmento RXR de la tercera orden
        </RXR>
    </RDE_O11.ORDER>
</RDE_O11>

Como podemos ver en la estructura del mensaje tenemos un elemento XML hijo del nodo raíz <RDE_O11> con el nombre <RDE_O11.ORDER> por cada grupo de repetición, que encierra el resto de elementos de los segmentos (o grupos) que lo componen.

Delimitadores en HL7 v2.xml

Los caracteres delimitadores especificados en el formato ER7 siguen representándose en la versión v2.xml en el segmento MSH.2:

<MSH>
    <MSH.1>|</MSH.1>
    <MSH.2>^~\& amp ;</MSH.2>
    ... resto de campos MSH
</MSH>

Aunque en la versión v2.xml no tendrían sentido, ya que los delimitadores de campos, componentes y subcomponentes son las etiquetas XML de cierre, se mantiene por compatibilidad. Principalmente por facilitar la conversión automática de ER7 a XML y viceversa.

Secuencias de escapado en HL7 v2.xml

En el caso del carácter separador de subcomponente «&» el formato en XML debe ser escapado, quedando en «\ & amp ;»

Respecto al escapado de caracteres especiales, teniendo en cuenta que en la versión v2.xml ya no se usan los delimitadores de ER7, pierde el sentido las secuencias de escapado que vimos en ER7. Así, no colisiona con ningún carácter especial los caracteres «|» ni «&» o «^».

Tampoco se reutiliza en HL7 v2.xml las secuencias de escapado \Xxxx\ o \Zxxx\ del ER7. En su lugar, se deberá utilizar el mecanismo de referencia de caracteres XML estándar para UTF-8, incluso los caracteres no imprimibles.

En definitiva, siendo un XML el producto final de la generación de un mensaje, se deben escapar los caracteres que aparezcan en los datos y que cualquier procesador XML pueda interpretar como carácter de marcado.

Diferencias entre la representación clásica ER7 y XML

Como resumen de todo lo anterior, la representación en XML está derivada de la codificación clásica en ER7, pero con ciertas diferencias que la hacen no-compatible. A pesar de ello, no es complicado hacer una conversión directa desde ER7 a XML o al revés. La codificación en ER7 tenía compatibilidad directa con las versiones anteriores, pero no se puede decir que XML no tenga del todo incompatibilidad, y es relativamente simple convertir.

Para empezar, además de las diferencias evidentes, la notación en XML lleva ciertas etiquetas con el tipo de datos en los componentes con tipos compuestos. En ER7 no se incluían. Por esto, en ER7 un cambio de tipo de datos compatible entre distintas versiones era directo, pero en XML al llevar etiquetas del tipo de datos, necesita cierto esfuerzo.

Los elementos XML de repetición de grupo de segmentos son otra diferencia que, en el caso de hacer una conversión de formatos XML a ER7 y viceversa, se debe considerar.

Como hemos visto, también las secuencias de escapado de caracteres especiales son diferentes, ya que en HL7 v2.xml se deben de utilizar los escapados propios de XML. Por ejemplo, el carácter «>» colisiona en XML pero no en ER7, mientras que el carácter «|» colisiona en ER7 pero no en XML.

Estructura de un mensaje HL7 v2

La definición abstracta de los mensajes HL7 permite representar la estructura de los mensajes. Un mensaje HL7 consiste en una secuencia de segmentos y grupos de segmentos. Como hemos visto anterioremente, cada segmento está compuesto a su vez de una secuencia ordenada de campos. Cada campo tiene unos atributos de tipo de datos, obligatoriedad (u opcionalidad), longitud y cardinalidad. Además está descrito por uno o varios componentes , y estos por subcomponentes.

Veamos un ejemplo de definición de estructura para ir detallando estos atributos sobre el mismo.

OMB^O27^OMB_O27Blood Product Order MessageOptCardinalidad
MSHMessage HeaderR[1..1]
--- PATIENT beginR[1..1]
PIDPatient IdentificationR[1..1]
--- PATIENT_VISIT beginR[1..1]
PV1Patient VisitR[1..1]
--- PATIENT_VISIT end
--- PATIENT end
{--- ORDER beginR[1..n]
ORCCommon OrderR[1..1]
--- TIMING begin[1..1]
TQ1Timing/QuantityR[1..1]
--- TIMING end
BPOBlood Product OrderR[1..1]
[ SPM ]SpecimenRE[0..1]
[ { DG1 } ]DiagnosisRE[0..n]
[ {--- OBSERVATION beginC[0..n]
OBXObservation/ResultR[1..1]
} ]--- OBSERVATION end
[ { NTE } ]Notes and Comments (for Order)RE[0..n]
}--- ORDER end

Obligatoriedad/Opcionalidad

En HL7 v2 se utiliza el concepto de opcionalidad, tanto para segmentos, grupos de segmentos, como para campos, componentes y subcomponentes.

En lo que refiere a la presencia de un elemento en la estructura del mensaje, HL7 no es muy flexible, y no es posible eliminar un elemento de la estructura, aunque no se utilice.

CódigoDefiniciónDescripción
RRequeridoEste elemento debe aparecer obligatoriamente en el mensaje
RERequerido / VacíoDebe aparecer si hay datos.
CCondicionalSu existencia está condicionada
CECondicional / VacíoCondicionado y puede ir vacío.
OOpcional
BCompatibilidad con versiones anteriores
WRetirado
XNo soportado

Cardinalidad

La cardinalidad expresa el grado de ocurrencias que debe tener un elemento en el mensaje. Está ligado con la opcionalidad en cuanto a la definición de apariciones que pueda haber del segmento.

En la definición abstracta podemos comprobar los siguientes símbolos, con sus respectivos significados:

SímboloSignificado
SEGSegmento requerido, una aparición
[ SEG ]Opcionalidad [0..1]
{ SEG }Repetición (conjunto de elementos) [1..n]
[{ SEG }]Conjunto opcional [0..n]

La simbología utilizada para la definición abstracta en cuanto a cardinalidad es bastante simple:

[n..m] : Mínimo n ocurrencias, y puede haber hasta m ocurrencias.

Con esta definición podemos suponer que:

CardinalidadDescripciónExplicación
[0..n]Opcionalidad con repetición.Puede, desde no haber ninguna ocurrencia del elemento hasta n ocurrencias.
[1..n]Obligatoriedad con repeticiónEl elemento debe estar presente, al menos 1 vez, y pueden haber hasta n veces.
[1..1]Obligatoriedad sin repetición.El elemento debe aparecer 1 vez.
[0..1]Opcionalidad sin repetición.El elemento puede o no estar presente, pero si aparece, solo una ocurrencia

Tipo de Datos

El estándar define varias clasificaciones para los tipos de datos que pueden incluir los mensajes en campos, componentes o subcomponentes. Básicamente podemos encontrar dos clases: básicos y compuestos. Nombraremos los mas generales y frecuentes a modo de ejemplo, pero un integrador necesita acceso al estándar como referencia, como poco a la guía de implementación.

Tipos básicos

SiglasNombreLong.Descripción
DTDate8Fecha en formato YYYYMMDD
DTMDate/Time15Fecha en formato YYYYMMDDHHmmss[.s]
FTFormatted Text65536Alfanumérico de fecha formateada
IDIdentifierVariableValor codificado en tabla HL7
ISIdentifier20Valor codificado por tabla TES
NMNumeric16Valor numérico
SISequence ID4Numérico secuencial
STStrng199Texto alfanumérico

Tipos compuestos

Los campos con tipos compuestos incorporarán componentes y/o subcomponentes, al ser una composición de tipos básicos. En muchas ocasiones los campos compuestos incluyen valores codificados, con textos o descripciones, y referencias a la tabla HL7 o sistema de codificación al que refieren.

Ejemplo:

CE (Coded Element)

Es un tipo de datos para valores codificados que se van a transmitir incluyendo un código y una descripción.

Seq.LenTipoNombreCard
120STIdentifier[1..1]
2199STText
[1..1]
320IDName of Coding System
[1..1]
420STAlternate Identifier
[0..1]
5199STAlternate Text
[0..1]
620IDName of Alternate Coding System
[0..1]

Un valor de ejemplo de este tipo podría ser, para el identificador F-11380 de la creatinina en el sistema CIE9 (I9), con código alternativo 2148-5 en el sistema de codificación LOINC (LN):

|F-11380^CREATININE^I9^2148-5^CREATININE^LN|

Reglas de construcción de mensajes

Uno de los aspectos mas interesantes, y necesarios, para poderse constituir un estándar es que, tanto emisor como receptor, conozcan las reglas por las que se construyen la mensajería. El que ambos puedan predecir ciertas reglas supone un trabajo de negocio ahorrado. Por otro lado permite la reutilización de los desarrollos y servicios en distintos ámbitos de aplicación, o con distintos proveedores.

Ya disponemos de suficiente información sobre un mensaje HL7 v2, en cuanto a estructura del mensaje y elementos y atributos. Podemos ver ahora cómo construir mensajes, qué reglas de construcción de mensajes define el estándar. Para ello nos valdremos de un algoritmo en pseudocódigo para la generación de mensajería HL7 v2 en formato ER7.

/*
    Como Precondición tenemos un array de datos a enviar para construir el mensaje HL7
    y tenemos que los caracteres separadores serán: <cr>, | ^ ~ & \
*/
procedure generar_mensaje (datos) {
    Identificar_tipo_mensaje();
    Identificar_separadores();
    validar (datos);
    ordenar_segmentos (datos, lista_segmentos); 
    foreach segmento in (lista_segmentos) {
        insertar segmento.nombre; /* por ejemplo, el primer segmento será MSH */
        / * Obtener campos del segmento iterando */
        foreach campo in (campos_de(segmento)) {
            insertar separador_campo; /* En nuestro casos seria el pipe '|' */
            /* Iterar repeticiones para campos que admiten repetición, o la única ocurrencia en caso contrario*/
            foreach ocurrencia in (ocurrencias_de(campo)) {
                /* Iterar componentes de la ocurrencia/repeticion */
                foreach componente in (componentes_de(ocurrencia)) {
                    obtener_datos_subcomponente(componente);
                    /* Iterar y obtener  los datos de los subcomponentes */
                    foreach subcomponente in (subcomponentes_de(componente)) {
                        /* escapar los delimitadores de ER7 definidos */
                        reemplazar(separador_campo,'\F\ ');                        
                        reemplazar(separador_componente, '\S\ ');
                        reemplazar(separador_repetición, '\R\ ');
                        reemplazar(caracter_de_escapado, '\E\ ');
                        reemplazar(separador_subcomponente, '\T\ ');
                        reemplazar(caracter_truncado, '\P\ ');
                        insertar subcomponente;
                        if not ultimo(subcomponente) 
                            insertar separador_subcomponente; /* el caracter & */
                    }
                if not ultimo(componente) 
                    insert separador_componente; /* caracter ^ */
                }    
            if not ultimo(ocurrencia)  
                insertar separador_repeticion; /* En este caso sería '~' */
            }
            salir si ultimo(campo);
        }
        insertar terminador_segmento; /* será un <cr>  */
    }
    return;
}



En el caso de HL7 v2.xml la generación de mensajes sigue un proceso similar, salvo las excepciones que se han comentado anteriormente, y que rigen por las propias del esquema v2.xml:

  • Cada elemento incluirá un elemento XML y se dejan de utilizar los separadores de segmento, campo, componente y subcomponente.
  • Los campos vacíos pueden omitirse en el mensaje.
  • Los segmentos de grupos incluyen un elemento XML del grupo.
  • Los tipos compuestos llevan un elemento XML con el descriptor del tipo de cada componente.

Modelo de interacción

El estándar define estos triggers o disparadores como eventos que ocurren en el mundo real, en el ámbito de la sanidad, y que crean la necesidad de que los datos fluyan entre distintos sistemas de información. La necesidad de interoperar los datos generados en dicho evento.

De esta manera, cada evento tendrá asociado un mensaje abstracto que define el tipo de información que debe interoperar entre los sistemas.

El modelo básico de transacciones en HL7 está compuesto de:

Transacciones HL7
Modelo de transacciones HL7
  1. Evento desencadenador de la transacción.
  2. Construcción de mensaje con la información interoperable en el sistema remitente.
  3. Recepción del mensaje en el sistema destino.
  4. Construcción de una respuesta al mensaje recibido en el sistema Destino.
  5. Envío de mensaje al sistema remitente.
  6. Recepción del mensaje en el sistema remitente.

Un ejemplo de evento disparador

Con el ejemplo de mensaje que estamos tratando tanto en ER7 como XML, un mensaje tipo OMB^O27, se trata por tanto de un mensaje de petición de transfusión (Blood Product Order Message).

Interacción de OMB^O27
Interacción de OMB^O27

Este tipo de mensajes se suele definir para el inicio de una transfusión. En el mensaje se pueden especificar los tipos de productos a transfundir, tales como Concentrado de Hematíes, Pool de Plaquetas, Plasma, etc.

Los eventos a los que puede corresponder este mensaje son:

  • Solicitud de transfusión: En algún punto del circuito funcional se requiere de una transfusión para el paciente. Programándola para una intervención planificada, o para transfundir inmediatamente, en el día o en las próximas horas.
  • Suspensión de transfusión: Antes de ser transfundida, el peticionario cancela la solicitud.
  • Actualización de datos de una solicitud de transfusión: Cualquier cambio en la solicitud, o inclusión de nueva información. Por ejemplo, un registro de la extracción e información de la pulsera de seguridad transfusional, indicación de un nuevo producto, etc.
  • Fin de transfusión: La estación clínica informa al sistema destinatario que la transfusión ha finalizado, con incidentes de reacción transfusional, o con éxito.

Protocolos de transporte

HL7 usó ASTM como la base para llegar a definir HL7 v2, pero el hecho de ser un protocolo sobre el nivel 7 de aplicación, no especifica ningún otro protocolo de transporte. Es posible utilizar cualquiera. Prácticamente desde que se publicó, los mecanismos de la capa de transporte mas utilizados con HL7 v2 fueron ficheros y socket TCP/IP.

En cuanto a la transmisión de los mensajes en ficheros, el único mecanismo de control necesario es el de semáforos de lectura mientras se completa escritura. Pero en la comunicación basada en socket TCP, trajo algún problema en cuanto al control del flujo de información, por lo que se diseñó el protocolo MLLP para el framing en la capa de sesión.

Tipos de mensajes HL7 v2

El estándar de esta versión define cientos de mensajes para comunicar partes de información clínica o administrativa cuando sucede algún evento.

Para cada ámbito de información se define un conjunto de mensajes distintos, que a su vez se diferencia en función del evento disparador de esa información generada.

La forma en que la documentación del estándar agrupa estos ámbitos de información es a través de distintos capítulos. De esta manera tenemos que, por ejemplo, para el estándar HL7 v.2.5 la distribución de capítulos donde se agrupan los mensajes correspondientes es como sigue.

Capitulos HL7
Capítulos HL7

Cada capítulo incluye la definición de los mensajes HL7 asociados al ámbito y a los eventos disparadores correspondientes.

Como ejemplo, entre los tipos de mensajes mas utilizados, en relación al ámbito están:

Tipos de Mensajes HL7 mas frecuentes
Tipos de Mensajes HL7 mas frecuentes

Dejar un comentario

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

Follow by Email
Facebook
Twitter
LinkedIn