Here is my code:
from hl7apy.parser import parse_messagehl7 = 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||||||UNICODEPID|1||7393670^^^^MR||Joan^JIang||19900804000000|FemalePV1|1||nk^^001OBR|1||20071207011|00001^Automated Count^99MRC||20080508140600|20080508150616|||John||||20080508150000||||||||||HM||||||||TEST
Here is my message in notepad++ where all characters are shown:
Best Answer
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_messagefrom hl7apy.core import Group, Segmenthl7 = """MSH|^~\&|SendingAPP|TEST|||20080617143943||ORU^R01|1|P|2.3.1||||||UNICODEPID|1||7393670^^^^MR||Joan^JIang||19900804000000|Female PV1|1||nk^^001OBR|1||20071207011|00001^AutomatedCount^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 parserfrom hl7apy.core import Group, Segmentfrom 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 e.g.
from hl7apy import parserfrom hl7apy.core import Group, Segmentfrom hl7apy.exceptions import UnsupportedVersionhl7 = 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.