public static void Translate_HL7_26() { // Change the path to point to your own file to test with var path = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\PharmacyTreatmentDispense.txt"); List <IEdiItem> ediItems; using (var reader = new Hl7Reader(path, "EdiFabric.Templates.Hl7", new Hl7ReaderSettings { ContinueOnError = true })) ediItems = reader.ReadToEnd().ToList(); foreach (var message in ediItems.OfType <EdiMessage>()) { if (!message.HasErrors) { // Message was successfully parsed MessageErrorContext mec; if (message.IsValid(out mec)) { // Message was successfully validated } else { // Message failed validation with the following validation issues: var validationIssues = mec.Flatten(); } } else { // Message was partially parsed with errors } } } // Add a breakpoint here, run in debug mode and inspect ediItems
/// <summary> /// Validate HL7 transactions from file after read /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\PharmacyTreatmentDispense.txt"); List <IEdiItem> hl7Items; using (var reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) hl7Items = reader.ReadToEnd().ToList(); var dispenses = hl7Items.OfType <TSRDSO13>(); foreach (var dispense in dispenses) { // Validate MessageErrorContext errorContext; if (!dispense.IsValid(out errorContext)) { // Report it back to the sender, log, etc. var errors = errorContext.Flatten(); } else { // dispense is valid, handle it downstream } } }
/// <summary> /// Reads file with a corrupt MSH and a valid MSH /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\CorruptMsh.txt"); // Set the continue on error flag to true List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7", new Hl7ReaderSettings() { ContinueOnError = true })) hl7Items = hl7Reader.ReadToEnd().ToList(); var readerErrors = hl7Items.OfType <ReaderErrorContext>(); if (readerErrors.Any()) { // The stream is corrupt Debug.WriteLine(readerErrors.First().Exception.Message); } var dispenses = hl7Items.OfType <TSRDSO13>(); foreach (var dispense in dispenses) { // All valid dispenses were extracted } }
/// <summary> /// Reads dispense and observations batched up in the same interchange. /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load to a stream Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\MixedTransactions.txt"); // 2. Read multiple transactions batched up in the same interchange using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) { while (hl7Reader.Read()) { // Process dispenses if no parsing errors var dispense = hl7Reader.Item as TSRDSO13; if (dispense != null && !dispense.HasErrors) { ProcessDispense(hl7Reader.CurrentInterchangeHeader, hl7Reader.CurrentGroupHeader, dispense); } // Process observations if no parsing errors var observation = hl7Reader.Item as TSORUR01; if (observation != null && !observation.HasErrors) { ProcessObservation(hl7Reader.CurrentInterchangeHeader, hl7Reader.CurrentGroupHeader, observation); } } } }
/// <summary> /// Apply custom validation for cross segment or data element scenarios /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\MedicalRecord.txt"); // The custom validation logic is applied in the template by implementing IEdiValidator. List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, (FHS fhs, BHS bhs, MSH msh) => typeof(TSMDMT02CustomValidation).GetTypeInfo())) hl7Items = hl7Reader.ReadToEnd().ToList(); // Get the dispense var dispense = hl7Items.OfType <TSMDMT02CustomValidation>().Single(); // Check that the custom validation was triggered MessageErrorContext errorContext; if (!dispense.IsValid(out errorContext)) { var customValidation = errorContext.Errors.FirstOrDefault(e => e.Message == "NTE segment is missing."); Debug.WriteLine(customValidation.Message); } }
/// <summary> /// Reads the HL7 stream with ADD segment, as a continuation of a DSC segment /// ORC loop contains a placeholder segment HXX. Segments of system type HXX are not validated and not parsed, but added as a whole. /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load to a stream Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\ObservationADD_DSC.txt"); // 2. Read all the contents List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, (FHS fhs, BHS bhs, MSH msh) => typeof(TSRDSO13TAdd).GetTypeInfo())) hl7Items = hl7Reader.ReadToEnd().ToList(); // 3. Pull the required transactions var observations = hl7Items.OfType <TSRDSO13TAdd> (); }
/// <summary> /// Reads the HL7 stream with DSC segment /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load to a stream Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\ObservationDSC.txt"); // 2. Read all the contents List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) hl7Items = hl7Reader.ReadToEnd().ToList(); // 3. Pull the required transactions var observations = hl7Items.OfType <TSORUR01> (); }
/// <summary> /// Reads the HL7 stream from start to end using type factory. Allows you to dynamically specify the exact template to be used for parsing. /// </summary> public static void RunWithTypeFactory() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load to a stream Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\PharmacyTreatmentDispenses.txt"); // 2. Read all the contents List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, TypeFactory)) hl7Items = hl7Reader.ReadToEnd().ToList(); // 3. Pull the required transactions var dispenses = hl7Items.OfType <TSRDSO13>(); }
/// <summary> /// Split a message into parts (blocks of segments) and read each part individually. /// Use to process large transactions with repeating loops. /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\MedicalRecord.txt"); // The split is driven by setting which class to split by in the template. // Set the class to inherit from EdiItem and the parser will automatically split by it. List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, (FHS fhs, BHS bhs, MSH msh) => typeof(TSMDMT02Splitter).GetTypeInfo(), new Hl7ReaderSettings { Split = true })) hl7Items = hl7Reader.ReadToEnd().ToList(); // Find all N1 loops, they are all different ediItems var obxLoop = hl7Items.OfType <TSMDMT02Splitter>().Where(m => m.LoopOBX != null).SelectMany(m => m.LoopOBX); Debug.WriteLine(string.Format("OBX parts {0}", obxLoop.Count())); }
/// <summary> /// Validate with custom HL7 codes, different than the standard HL7 codes. Load the code dynamically at runtime. /// </summary> public static void Run2() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // Set HL7 codes map where the original code type will be substituted with the partner-specific code type var codeSetMap = new Dictionary <string, List <string> >(); codeSetMap.Add("HL7_ID_136", new List <string> { "N", "Y", "M" }); Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\MixedTransactions.txt"); List <IEdiItem> hl7Items; using (var reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) hl7Items = reader.ReadToEnd().ToList(); var dispenses = hl7Items.OfType <TSRDSO13>(); foreach (var dispense in dispenses) { // Validate using HL7 codes map MessageErrorContext errorContext; if (!dispense.IsValid(out errorContext, new ValidationSettings { DataElementCodesMap = codeSetMap })) { // Report it back to the sender, log, etc. var errors = errorContext.Flatten(); } else { // dispense is valid, handle it downstream } } }
/// <summary> /// Copy a message and remove unwanted parts. /// </summary> public static void RunWithCopy() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\MedicalRecord.txt"); // The split is driven by setting which class to split by in the template. // Set the class to inherit from EdiItem and the parser will automatically split by it. List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) hl7Items = hl7Reader.ReadToEnd().ToList(); var medRecords = hl7Items.OfType <TSMDMT02>(); var splitMedRecords = new List <TSMDMT02>(); foreach (var medRecord in medRecords) { foreach (var obxLoop in medRecord.LoopOBX) { var splitMedRecord = medRecord.Copy() as TSMDMT02; splitMedRecord.LoopOBX.RemoveAll(l => splitMedRecord.LoopOBX.IndexOf(l) != medRecord.LoopOBX.IndexOf(obxLoop)); splitMedRecords.Add(splitMedRecord); } } foreach (var medRecord in medRecords) { Debug.WriteLine(string.Format("Original: Med Record - OBX parts {0}", medRecord.LoopOBX.Count())); } foreach (var splitMedRecord in splitMedRecords) { Debug.WriteLine(string.Format("Split: Med Record - OBX parts {0}", splitMedRecord.LoopOBX.Count())); } }
/// <summary> /// Serialize an HL7 object to XML using DataContractSerializer /// </summary> public static void WithDataContractSerializer() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\PharmacyTreatmentDispense.txt"); List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) { hl7Items = hl7Reader.ReadToEnd().ToList(); } var transactions = hl7Items.OfType <TSRDSO13>(); foreach (var transaction in transactions) { var xml = transaction.SerializeDataContract(); Debug.WriteLine(xml.Root.ToString()); } }
/// <summary> /// Serialize an HL7 object to Json using Json.NET /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\PharmacyTreatmentDispense.txt"); List <IEdiItem> hl7Items; using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) { hl7Items = hl7Reader.ReadToEnd().ToList(); } var transactions = hl7Items.OfType <TSRDSO13>(); foreach (var transaction in transactions) { var json = Newtonsoft.Json.JsonConvert.SerializeObject(transaction); Debug.WriteLine(json.ToString()); } }
/// <summary> /// Reads one item at a time from the HL7 stream. /// Use for interchanges containing multiple transactions. /// The sample file contains two purchase orders - a valid one and an invalid one. /// </summary> public static async void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load to a stream Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\PharmacyTreatmentDispenses.txt"); // 2. Read item by item, that is each call to Read() // brings back either a control segment (or a transaction using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) { while (await hl7Reader.ReadAsync()) { // 3. Check if current item is dispense var dispense = hl7Reader.Item as TSRDSO13; if (dispense != null) { ProcessDispense(hl7Reader.CurrentInterchangeHeader, hl7Reader.CurrentGroupHeader, dispense); } } } }
/// <summary> /// Validate the typed control segments /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); Stream hl7Stream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\MixedTransactions.txt"); using (var hl7Reader = new Hl7Reader(hl7Stream, "EdiFabric.Templates.Hl7")) { while (hl7Reader.Read()) { var fhs = hl7Reader.Item as FHS; if (fhs != null) { // Validate var fhsErrors = fhs.Validate(); // Pull the sending application from FHS var senderId = fhs.FileSendingApplication_03.NamespaceID_01; Debug.WriteLine("Sending application:"); Debug.WriteLine(senderId); } var bhs = hl7Reader.Item as BHS; if (bhs != null) { // Validate var bhsErrors = bhs.Validate(); // Pull the sending application from BHS var senderId = bhs.BatchSendingApplication_03.NamespaceID_01; Debug.WriteLine("Sending application:"); Debug.WriteLine(senderId); } } } }