/// <summary> /// Parses the received HL7 message. /// </summary> /// <param name="messageForm">The raw message encoded in HL7 'pipes and hats' format.</param> /// <returns>The parsed HL7 message object</returns> /// <exception cref="HL7ParseException">Thrown when parsing fails</exception> public static HL7Message Parse(string messageForm) { // Determine the HL7 separators dynamically from the incoming message (usually "|^~\&") HL7Separators sep = new HL7Separators(messageForm); // Change CRLF or LF into the standard CR separators if (messageForm.Contains("\r\n")) { messageForm = messageForm.Replace("\r\n", "\r"); } if (messageForm.Contains("\n")) { messageForm = messageForm.Replace("\n", "\r"); } // Remove consecutive segment separators while (messageForm.Contains("\r\r")) { messageForm = messageForm.Replace("\r\r", "\r"); } // Parse all the segments messageForm = messageForm.TrimEnd(new char[] { sep.SegmentSeparator }); string[] segmentForm = messageForm.Split(sep.SegmentSeparator); for (int count = 0; count < segmentForm.Count(); count++) { segmentForm[count] = segmentForm[count].Replace("\n", string.Empty); } HL7Segment[] segments = new HL7Segment[segmentForm.Length]; for (int i = 0; i < segmentForm.Length; i++) { segments[i] = HL7Segment.Parse(segmentForm[i], sep); } // Grab the MSH segment in order to determine which message structure to use MSH msh = segments[0] as MSH; if (msh == null) { throw new HL7ParseException(ConstantsResource.HL7NoMshSegment); } if (msh.MessageType == null) { throw new HL7ParseException(ConstantsResource.NoMessageType); } // Determine the structure for the indicated message identifier Type messageStructure = GetMessageStructure(msh.MessageType); // Create the message and populate all the matching segments into its structure int segmentIndex = 0; HL7Message message = BuildSegmentGroup(messageStructure, segments, ref segmentIndex) as HL7Message; return(message); }
/// <summary> /// Encode segment group according to HL7 encoding rules with specified separators. /// </summary> /// <param HL7Name="seps">Characters to separate segments, fields, field repeats, components and subcomponents</param> /// <param HL7Name="sb">String builder</param> public void Encode(HL7Separators seps, StringBuilder sb) { var segmentGroupFields = GetType().GetFields().OrderBy(f => f.MetadataToken); foreach (FieldInfo segmentGroupField in segmentGroupFields) { if (segmentGroupField.FieldType.IsArray) { Array array = segmentGroupField.GetValue(this) as Array; foreach (object segmentGroupObject in array) { // Each item in the array could be another group of segments or a single segment if (segmentGroupObject is HL7SegmentGroup) { HL7SegmentGroup segmentGroup = segmentGroupObject as HL7SegmentGroup; segmentGroup.Encode(seps, sb); } else { HL7Segment segment = segmentGroupObject as HL7Segment; segment.Encode(seps, sb); sb.Append(seps.SegmentSeparator); } } } else { // The non-repeating item could be a another group of segments, or a single segment, or null object segmentGroupObject = segmentGroupField.GetValue(this); if (segmentGroupObject is HL7SegmentGroup) { HL7SegmentGroup segmentGroup = segmentGroupObject as HL7SegmentGroup; segmentGroup.Encode(seps, sb); } else if (segmentGroupObject != null) { HL7Segment segment = segmentGroupObject as HL7Segment; segment.Encode(seps, sb); sb.Append(seps.SegmentSeparator); } } } }
public static HL7Segment Parse(string segmentForm, HL7Separators sep) { // Split the segment into fields and create the object for the indicated segment identifier string[] fieldForm = segmentForm.Split(sep.FieldSeparator); HL7Segment segment = CreateBlankSegment(fieldForm[0]); if (segment == null) { return(new UnknownSegment() { FieldForm = fieldForm }); } // Parse each of the fields according to its declared identifier in the segment structure. // Some fields will be repeating, some will be strings and some will have components. PopulateSegment(sep, fieldForm, segment); return(segment); }
/// <summary> /// Parses each of the fields according to its declared identifier in the segment structure. /// Ignores any extra fields either in the received segment or in the structure. /// </summary> /// <param HL7Name="sep">Separators to use for repeating fields, components and subcomponents</param> /// <param HL7Name="fieldForm">Encoded segment split into fields, where fieldForm[0] is the segment name</param> /// <param HL7Name="segment">Empty object of desired segment structure</param> private static void PopulateSegment(HL7Separators sep, string[] fieldForm, HL7Segment segment) { FieldInfo[] fields = segment.GetType().GetFields(); // Subtract one from the number of fields in the received segment to avoid counting the segment name. int offset = 1; // Except when segment is MSH, then have no offset but the first field is the field separator. if (fieldForm[0].Equals("MSH")) { fields[0].SetValue(segment, "" + sep.FieldSeparator); offset = 0; } int n = Math.Min(fields.Length, fieldForm.Length - 1); for (int i = 1 - offset; i < n; i++) { object value = HL7Field.Parse(fields[i].FieldType, fieldForm[i + offset], sep); fields[i].SetValue(segment, value); } }