简体   繁体   中英

How to correctly parse an HL7 message using python HL7Apy?

Here is my code:

from hl7apy.parser import parse_message

hl7 = open("hl7.txt", "r").read()
msg = parse_message(hl7)
print(msg.children)

result:

[<Segment MSH>]

It shows only the first segment , seems simple but I don't know what i'm doing wrong.

I've tried from a text file, passing the message directly or even with another HL7 message, but always got same results.

Here is the message:

MSH|^~\&|SendingAPP|TEST|||20080617143943||ORU^R01|1|P|2.3.1||||||UNICODE
PID|1||7393670^^^^MR||Joan^JIang||19900804000000|Female
PV1|1||nk^^001
OBR|1||20071207011|00001^Automated Count^99MRC||20080508140600|20080508150616|||John||||20080508150000||||||||||HM||||||||TEST

Here is my message in notepad++ where all characters are shown: 记事本++中的消息

I think your issue is the the MLLP constant for HL7apy is a Carriage return \\r . If you replace the new line characters \\n the groups will parse out fine

from hl7apy.parser import parse_message
from hl7apy.core import Group, Segment

hl7 = """
MSH|^~\&|SendingAPP|TEST|||20080617143943||ORU^R01|1|P|2.3.1||||||UNICODE
PID|1||7393670^^^^MR||Joan^JIang||19900804000000|Female PV1|1||nk^^001
OBR|1||20071207011|00001^Automated
Count^99MRC||20080508140600|20080508150616|||John||||20080508150000||||||||||HM||||||||TEST
"""

msg = parse_message(hl7.replace('\n', '\r'), find_groups=True, validation_level=2)
print(msg.children)
print(msg.children[1].children)

for segment in msg.children:
    if isinstance(segment, Segment):
        for attribute in segment.children:
            print(attribute, attribute.value)
    if isinstance(segment, Group):
        for group in segment.children:
            for group_segment in group.children:
                for attribute in group_segment.children:
                    print(attribute, attribute.value)

Additionaly to the answer above you can use an exception handler

from hl7apy import parser
from hl7apy.core import Group, Segment
from hl7apy.exceptions import UnsupportedVersion

and use it like this

 try:
     msg = parser.parse_message(hl7)
 except UnsupportedVersion:
     msg = parser.parse_message(hl7.replace("n", "r"))

If your message is correct you can acces the contents of fields like this

 print(msg.ORU_R01_PATIENT_RESULT.ORU_R01_PATIENT.PID.PID_7.value)
 print(msg.ORU_R01_PATIENT_RESULT.ORU_R01_PATIENT.ORU_R01_VISIT.PV1.PV1_1.value)
 print(msg.ORU_R01_PATIENT_RESULT.ORU_R01_ORDER_OBSERVATION.OBR.OBR_3.value)

So an enhanced answer showing all groups and subgroups - but still not perfect - can be eg

from hl7apy import parser
from hl7apy.core import Group, Segment
from hl7apy.exceptions import UnsupportedVersion

hl7 = open("hl7.txt", "r").read()

try:
    msg = parser.parse_message(hl7.replace('\n', '\r'), find_groups=True, validation_level=2)
except UnsupportedVersion:
    msg = parser.parse_message(hl7.replace('\n', '\r'), find_groups=True, validation_level=2)

indent = "    "
indent_seg = "    "
indent_fld = "        "

def subgroup (group, indent):
    indent = indent + "    "
    print (indent , group)
    for group_segment in group.children:
        if isinstance(group_segment, Group):
            subgroup (group_segment)
        else: 
            print(indent_seg, indent ,group_segment)
            for attribute in group_segment.children:
                print(indent_fld, indent ,attribute, attribute.value)


def showmsg (msg):
    print(msg.children[1])
    for segment in msg.children:
        if isinstance(segment, Segment):
            print (indent ,segment)
            for attribute in segment.children:
                print(indent_fld, indent, attribute, attribute.value)
        if isinstance(segment, Group):
            for group in segment.children:
                print (indent,group)
                for group_segment in group.children:
                    if isinstance (group_segment, Group): 
                        subgroup (group_segment, indent)
                    else:
                        print(indent_seg, indent ,group_segment)
                        for attribute in group_segment.children:
                            print(indent_fld, indent, attribute, attribute.value)

showmsg (msg)     

can give a result like this

<Group ORU_R01_PATIENT_RESULT>
    <Segment MSH>
             <Field MSH_1 (FIELD_SEPARATOR) of type ST> |
             <Field MSH_2 (ENCODING_CHARACTERS) of type ST> ^~\&
             <Field MSH_3 (SENDING_APPLICATION) of type HD> SendingAPP
             <Field MSH_4 (SENDING_FACILITY) of type HD> TEST
             <Field MSH_7 (DATE_TIME_OF_MESSAGE) of type TS> 20080617143943
             <Field MSH_9 (MESSAGE_TYPE) of type MSG> ORU^R01
             <Field MSH_10 (MESSAGE_CONTROL_ID) of type ST> 1
             <Field MSH_11 (PROCESSING_ID) of type PT> P
             <Field MSH_12 (VERSION_ID) of type VID> 2.3.1
             <Field MSH_18 (CHARACTER_SET) of type ID> UNICODE
    <Group ORU_R01_PATIENT>
         <Segment PID>
             <Field PID_1 (SET_ID_PID) of type SI> 1
             <Field PID_3 (PATIENT_IDENTIFIER_LIST) of type CX> 7393670^^^^MR
             <Field PID_5 (PATIENT_NAME) of type XPN> Joan^JIang
             <Field PID_7 (DATE_TIME_OF_BIRTH) of type TS> 19900804000000
             <Field PID_8 (SEX) of type IS> Female
        <Group ORU_R01_VISIT>
             <Segment PV1>
                 <Field PV1_1 (SET_ID_PV1) of type SI> 1
                 <Field PV1_3 (ASSIGNED_PATIENT_LOCATION) of type PL> nk^^001
    <Group ORU_R01_ORDER_OBSERVATION>
         <Segment OBR>
             <Field OBR_1 (SET_ID_OBR) of type SI> 1
             <Field OBR_3 (FILLER_ORDER_NUMBER) of type EI> 20071207011
             <Field OBR_4 (UNIVERSAL_SERVICE_ID) of type CE> 00001^Automated Count^99MRC
             <Field OBR_6 (REQUESTED_DATE_TIME) of type TS> 20080508140600
             <Field OBR_7 (OBSERVATION_DATE_TIME) of type TS> 20080508150616
             <Field OBR_10 (COLLECTOR_IDENTIFIER) of type XCN> John
             <Field OBR_14 (SPECIMEN_RECEIVED_DATE_TIME) of type TS> 20080508150000
             <Field OBR_24 (DIAGNOSTIC_SERV_SECT_ID) of type ID> HM
             <Field OBR_32 (PRINCIPAL_RESULT_INTERPRETER) of type NDL> TEST1
    <Group ORU_R01_ORDER_OBSERVATION>
         <Segment OBR>
             <Field OBR_1 (SET_ID_OBR) of type SI> 2
             <Field OBR_3 (FILLER_ORDER_NUMBER) of type EI> 20071207011
             <Field OBR_4 (UNIVERSAL_SERVICE_ID) of type CE> 00001^Automated Count^99MRC
             <Field OBR_6 (REQUESTED_DATE_TIME) of type TS> 20080508140600
             <Field OBR_7 (OBSERVATION_DATE_TIME) of type TS> 20080508150616
             <Field OBR_10 (COLLECTOR_IDENTIFIER) of type XCN> John
             <Field OBR_14 (SPECIMEN_RECEIVED_DATE_TIME) of type TS> 20080508150000
             <Field OBR_24 (DIAGNOSTIC_SERV_SECT_ID) of type ID> HM
             <Field OBR_32 (PRINCIPAL_RESULT_INTERPRETER) of type NDL> TEST2
        <Group ORU_R01_OBSERVATION>
             <Segment OBX>
                 <Field OBX_1 (SET_ID_OBX) of type SI> 1
                 <Field OBX_2 (VALUE_TYPE) of type ID> 2

by disabling find_groups like this msg = parser.parse_message(hl7, find_groups=False) My messages are now parsed correctly.

Thx to @sqlab and @badger0053 for help, i was able to make a progression.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM