-
Notifications
You must be signed in to change notification settings - Fork 156
Decoding a message
var message = @"MSH|^~\&|CohieCentral|COHIE|Clinical Data Provider|TCH|20060228155525||QRY^R02^QRY_R02|1|P|2.3|QRD|20060228155525|R|I||||10^RD&Records&0126|38923^^^^^^^^&TCH|||";
var parser = new PipeParser();
var parsed = parser.Parse(message);
var qryR02 = parsed as QRY_R02;
Assert.IsNotNull(qryR02);
Assert.AreEqual("38923", qryR02.QRD.GetWhoSubjectFilter(0).IDNumber.Value);
What happens if there is a segment in an HL7 message which is not expected? See below for some examples of what that means...
- A segment appears in the message payload for a given message type i.e.
ADT_A01
which is not defined in the specification for that message type. - A segment repeats which should not repeat (according to the specification)
- A segment appears out of sequence (according to the HL7 specification segment sequence is important)
- A non-standard segment appears in the message payload.
The example below shows a (non-standard) message payload for message type ADT_A01
and how to access the out of sequence segment data. In this message type the NK1
segments should come after the PID
segment and before the PV1
segment (according to the V2.3 HL7 specification).
Instead of parsing these segments and inserting them into the existing (standard) group NK1
it creates a new (2nd) group and appends the occurrence of the group to the end of the group name NK1{group occurrence}
i.e. the 2nd NK1
group would be called NK12
and a 3rd group would be NK13
and so on.
It does this because the parser has already moved on passed the original (standard) group and not found any NK1
segments to parse and will not make any assumptions about where the segment should go, especially when there are groups of repeatable segments such as Procedure
or Insurance
.
[Test]
public void Parse_V23_ADT_A01()
{
var message =
"MSH|^~\\&|V500|01010|TEST|TEST|20170130125848||ADT^A01|12345||2.3||||||8859/1\r"
+ "EVN|A01|20170130125600|||12345|20170130125600\r"
+ "PID|1|12345^^^PATIENT MASTER^MRN^|12345^^^PATIENT MASTER^MRN^||TEST||20101114|F||4|16 Bothar Na Tra^^Ireland^^^1101^home^^||||2303|1||12345^^^EPISODE NUMBER^FIN NBR^|12312312310||||||0|Not Known / Not Stated||1101||\r"
+ "PV1|1|I|TEST^08^011^A207^^Bed(s)^A207|01||^^^^^^|0121212J^Stephen^Peter^J^^Dr^^^Doctor Provider Number^Personnel^^^DOCUPIN^|||ONC|||1|01|||0121212J^Stephen^Peter^J^^Dr^^^Doctor Provider Number^Personnel^^^DOCUPIN^|8|12345^0^^^Visit Id|5M^20170130125600|||||||||||||||||||B2021||Active|||20170130125600\r"
+ "NK1|1||||0404111111^^^test@test.com||Proxy\r"
+ "NK1|2||||0404111112^^^test2@test.com||Proxy 2";
var parser = new PipeParser();
var adtA01 = (NHapi.Model.V23.Message.ADT_A01)parser.Parse(message);
var allNextOfKin = adtA01.GetAll("NK12");
Assert.IsNotNull(allNextOfKin);
Assert.That(nextOfKinGroup2, Has.Count.EqualTo(2));
Assert.AreEqual(
"test@test.com",
((Model.V23.Segment.NK1)allNextOfKin[0]).GetPhoneNumber(0).EmailAddress.Value);
Assert.AreEqual(
"test2@test.com",
((Model.V23.Segment.NK1)allNextOfKin[1]).GetPhoneNumber(0).EmailAddress.Value);
}
What happens if the unexpected segments do not follow on from each other?
[Test]
public void Parse_V23_ADT_A01()
{
var message =
"MSH|^~\\&|V500|01010|TEST|TEST|20170130125848||ADT^A01|12345||2.3||||||8859/1\r"
+ "EVN|A01|20170130125600|||12345|20170130125600\r"
+ "PID|1|12345^^^PATIENT MASTER^MRN^|12345^^^PATIENT MASTER^MRN^||TEST||20101114|F||4|16 Bothar Na Tra^^Ireland^^^1101^home^^||||2303|1||12345^^^EPISODE NUMBER^FIN NBR^|12312312310||||||0|Not Known / Not Stated||1101||\r"
+ "PV1|1|I|TEST^08^011^A207^^Bed(s)^A207|01||^^^^^^|0121212J^Stephen^Peter^J^^Dr^^^Doctor Provider Number^Personnel^^^DOCUPIN^|||ONC|||1|01|||0121212J^Stephen^Peter^J^^Dr^^^Doctor Provider Number^Personnel^^^DOCUPIN^|8|12345^0^^^Visit Id|5M^20170130125600|||||||||||||||||||B2021||Active|||20170130125600\r"
+ "NK1|1||||0404111111^^^test@test.com||Proxy\r"
+ "IN1|0001|2|314000|||||||||19800101|||1|BARDOUN^LEA SACHA|1|19981201|AVENUE FRANC GOLD 8^^LUXEMBOURGH^^6780^150|||||||||||||||||\r"
+ "NK1|2||||0404111112^^^test2@test.com||Proxy 2";
var parser = new PipeParser();
var adtA01 = (NHapi.Model.V23.Message.ADT_A01)parser.Parse(message);
var nextOfKinGroup2 = adtA01.GetAll("NK12");
Assert.IsNotNull(nextOfKinGroup2);
Assert.That(nextOfKinGroup2, Has.Count.EqualTo(1));
Assert.AreEqual(
"test@test.com",
((Model.V23.Segment.NK1)nextOfKinGroup2[0]).GetPhoneNumber(0).EmailAddress.Value);
var nextOfKinGroup3 = adtA01.GetAll("NK13");
Assert.IsNotNull(nextOfKinGroup2);
Assert.That(nextOfKinGroup3, Has.Count.EqualTo(1));
Assert.AreEqual(
"test2@test.com",
((Model.V23.Segment.NK1)nextOfKinGroup3[0]).GetPhoneNumber(0).EmailAddress.Value);
}
Some message types are not mapped to their exact same event type which can cause some confusion when you first encounter it.
For example, ADT^A01, ADT^A04, ADT^A08 and ADT^A13 event types will all be parsed into the ADT^01 structure.
The following unit test illustrates this behaviour:
[Test]
public void TestADTA04IsMappedAsA01()
{
var hl7Data = @"MSH|^~\&|CohieCentral|COHIE|Clinical Data Provider|TCH|20060228155525||ADT^A04|1|P|2.5.1|
EVN|
PID|1|12345
PV1|1";
var parser = new PipeParser();
var msg = parser.Parse(hl7Data);
Assert.IsNotNull(msg, "Message should not be null");
var a04 = (ADT_A01)msg;
Assert.AreEqual("A04", a04.MSH.MessageType.TriggerEvent.Value);
Assert.AreEqual("1", a04.PID.SetIDPID.Value);
}
The Event to Structure Map for each version of HL7 supported can be found below: