/// <summary> ///实现处理的接口 /// </summary> /// <param name="message">传入的消息字符</param> /// <returns></returns> public string Process(string message) { IMessage m = null; try { m = parser.Parse(message); } catch (Exception ex) { //MediII.Common.LogHelper.LogError(string.Format("消息消息失败,传入消息为:\n\r{0}",message),LogCatagories.AdapterBiz); string sendingApp = System.Configuration.ConfigurationManager.AppSettings["SedingApplication"]; string recvApp = "MediII"; string ackMsg = MediII.Common.MessageHelper.SetACK("ACK", "", "", sendingApp, sendingApp, recvApp, recvApp, "123456789", ex.Message); return(ackMsg); } ISegment msh = (ISegment)m.GetStructure("MSH"); string messageID = Terser.Get(msh, 10, 0, 1, 1); string guid = MediII.Common.GUIDHelper.NewGUID(); OnProcessing(guid, messageID, message); string ack = DoProcess(m); OnProcessed(guid, parser.GetAckID(ack), ack, true); return(ack); }
/// Create an Ack message based on a received message/// /// received message/// /// Acknowlegde code/// /// Message to be created/// /// Created message public string MakeACK(string AckHead, string version, string ackCode, IMessage ackMessage) { // Create a Terser instance for the outbound message (the ACK). Terser terser = new Terser(ackMessage); // Populate outbound MSH fields using data from inbound message // Now set the message type, HL7 version number, acknowledgement code // and message control ID fields: string sendingApp = terser.Get("/MSH-3"); string sendingEnv = terser.Get("/MSH-4"); string CommunicationNameOfThisApplication = string.Empty; string EnvironmentIdentifierOfThisApplication = string.Empty; terser.Set("/MSH-3", CommunicationNameOfThisApplication); terser.Set("/MSH-4", EnvironmentIdentifierOfThisApplication); terser.Set("/MSH-5", sendingApp); terser.Set("/MSH-6", sendingEnv); terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh")); terser.Set("/MSH-9", "ACK"); terser.Set("/MSH-12", version); // The ackCode should be "AA" if the message was correctly handled and "AE" if there was an error terser.Set("/MSA-1", ackCode == null ? "AA" : ackCode); terser.Set("/MSA-2", AckHead); return(PipeParser.Encode(ackMessage, new EncodingCharacters('|', '^', '~', '\\', '&'))); }
/// <summary> /// Validate the message /// </summary> internal static void Validate(IMessage message, ISystemConfigurationService config, List <IResultDetail> dtls, IServiceProvider context) { // Structure validation PipeParser pp = new PipeParser() { ValidationContext = new DefaultValidation() }; try { pp.Encode(message); } catch (Exception e) { dtls.Add(new ValidationResultDetail(ResultDetailType.Error, e.Message, e)); } // Validation of sending application try { Terser msgTerser = new Terser(message); object obj = msgTerser.getSegment("MSH") as NHapi.Model.V25.Segment.MSH; if (obj != null) { var msh = obj as NHapi.Model.V25.Segment.MSH; var domainId = new ComponentUtility() { Context = context }.CreateDomainIdentifier(msh.SendingApplication, dtls); if (!config.IsRegisteredDevice(domainId)) { dtls.Add(new UnrecognizedSenderResultDetail(domainId)); } } else { obj = msgTerser.getSegment("MSH") as NHapi.Model.V231.Segment.MSH; if (obj != null) { var msh = obj as NHapi.Model.V231.Segment.MSH; var domainId = new ComponentUtility() { Context = context }.CreateDomainIdentifier(msh.SendingApplication, dtls); if (!config.IsRegisteredDevice(domainId)) { dtls.Add(new UnrecognizedSenderResultDetail(domainId)); } } else { dtls.Add(new MandatoryElementMissingResultDetail(ResultDetailType.Error, "Missing MSH", "MSH")); } } } catch (Exception e) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } }
public void Parse_UnknownMessageType_ReturnsGenericMessage(string version, Type expectedType) { // Arrange // a valid ORU_R01 message in which MSH-9 has been changed var input = $"MSH|^~\\&|LABGL1||DMCRES||19951002185200||ZZZ^ZZZ|LABGL1199510021852632|P|{version}\r" + "PID|||T12345||TEST^PATIENT^P||19601002|M||||||||||123456\r" + "PV1|||NER|||||||GSU||||||||E||||||||||||||||||||||||||19951002174900|19951006\r" + "OBR|1||09527539437000040|7000040^ETHANOL^^^ETOH|||19951002180500|||||||19951002182500||||1793561||0952753943||19951002185200||100|F||^^^^^RT\r" + "OBX||NM|7000040^ETHANOL^^^ETOH|0001|224|mg/dL|||||F|||19951002185200||182\r" + "NTE||| Reference Ranges\r" + "NTE||| ****************\r" + "NTE||| Normal: Negative\r" + "NTE||| Toxic Concentration: >80 mg/dL\r"; var expectedMsh5 = "DMCRES"; var expectedObx2 = "NM"; var sut = new PipeParser(); // Act var message = sut.Parse(input); sut.Encode(message); var terser = new Terser(message); // Assert Assert.AreEqual(expectedType, message.GetType()); Assert.AreEqual(expectedMsh5, terser.Get("/MSH-5")); Assert.AreEqual(expectedObx2, terser.Get("/OBX-2")); }
private void FillMSHSegment(ISegment mshIn, ISegment mshOut) { if (mshOut == null) { throw new System.Exception("mshout"); } Guid g = Guid.NewGuid(); Terser.Set(mshIn, 7, 0, 1, 1, DateTime.Now.ToString("yyyyMMddHHmmss")); Terser.Set(mshIn, 7, 0, 1, 1, DateTime.Now.ToString("yyyyMMddHHmmss")); if (mshIn == null) { Terser.Set(mshIn, 3, 0, 1, 1, ""); Terser.Set(mshIn, 4, 0, 1, 1, ""); Terser.Set(mshIn, 5, 0, 1, 1, ""); Terser.Set(mshIn, 6, 0, 1, 1, ""); Terser.Set(mshIn, 9, 0, 1, 1, "ACK"); } else { Terser.Set(mshIn, 3, 0, 1, 1, Terser.Get(mshIn, 5, 0, 1, 1)); Terser.Set(mshIn, 4, 0, 1, 1, Terser.Get(mshIn, 6, 0, 1, 1)); Terser.Set(mshIn, 5, 0, 1, 1, Terser.Get(mshIn, 3, 0, 1, 1)); Terser.Set(mshIn, 6, 0, 1, 1, Terser.Get(mshIn, 4, 0, 1, 1)); Terser.Set(mshIn, 9, 0, 1, 1, Terser.Get(mshIn, 9, 0, 1, 1)); Terser.Set(mshIn, 9, 0, 2, 1, Terser.Get(mshIn, 9, 0, 2, 1)); } }
private void SetACK(AckTypes ackType, String messageString) { Terser terser = new Terser(hl7Ack.Message); ISegment err = terser.getSegment("/ERR(0)"); ISegment criticalSegment = TryToRecoverCriticalDataFromMessage(messageString); try { FillMSHSegment((ISegment)hl7Ack.Message.GetStructure("MSH"), criticalSegment); if (criticalSegment == null) { terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackType)); terser.Set("/MSA-2", ""); } else { terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackType)); terser.Set("/MSA-2", Terser.Get(criticalSegment, 10, 0, 1, 1)); } } catch (HL7Exception he) { _errorMessage.Append(he.Message); return; //do not throw exceptions; } //terser.Set("ERR(0)-7", _errorMessage); terser.Set("/ERR(0)-7-1-1", _errorMessage.ToString()); }
public override bool Send(IMessage msg) { bool result = true; EditMessageHeader(msg); try { PipeParser parser = new PipeParser(); string res = SendRequest(parser.Encode(msg)); IMessage response = parser.Parse(res); HLMessageToDB hl7message = new HLMessageToDB(); hl7message.HL7MessageToDB(Convert.ToString(msg)); Terser terser = new Terser(response); string ackCode = terser.Get("/MSA-1"); result = (ackCode == "AA"); } catch (Exception ex) { Logger.ErrorFormat("Error in delivering message '{0}' to Http endpoint with uri '{1}'. Error: {2}", msg.GetStructureName(), serverUri, ex.Message); result = false; } return(result); }
/// <summary> /// Creates a negative acknowledgement message. /// </summary> /// <param name="request">The request message to use to create the response message.</param> /// <param name="responseCode">The response code of the message.</param> /// <param name="errCode">The error code of the message.</param> /// <param name="errDescription">The error description of the message.</param> /// <returns>Returns the created negative acknowledgement message instance.</returns> public static IMessage CreateNack(IMessage request, string responseCode, string errCode, string errDescription) { MessageUtil.tracer.TraceEvent(TraceEventType.Warning, 0, $"NACK Condition : {errDescription}"); if (request.Version == "2.3.1") { var ack = new ACK(); var terser = new Terser(ack); terser.Set("/MSA-1", responseCode); terser.Set("/MSA-3", "Error occurred"); terser.Set("/MSA-6-1", errCode); terser.Set("/MSA-6-2", errDescription); UpdateMSH(terser, request); return(ack); } else { var ack = new NHapi.Model.V25.Message.ACK(); var terser = new Terser(ack); terser.Set("/MSA-1", responseCode); UpdateMSH(terser, request); terser.Set("/ERR-3-1", errCode); terser.Set("/ERR-3-2", errDescription); return(ack); } }
public void TestMultiArg() { var msh = suiS12.MSH; var test = Terser.Get(msh, 9, 0, 2, 1); Assert.AreEqual("a", test); }
/// <summary> Populates the given error segment with information from this Exception.</summary> // TODO: this is out of sync with hapi see // https://github.com/hapifhir/hapi-hl7v2/blob/809516e3f4851d7cd97573efb6dedf24959a1063/hapi-base/src/main/java/ca/uhn/hl7v2/AbstractHL7Exception.java#L134 public virtual void populate(ISegment errorSegment) { //make sure it's an ERR if (!errorSegment.GetStructureName().Equals("ERR")) { throw new HL7Exception("Can only populate an ERR segment with an exception -- got: " + errorSegment.GetType().FullName); } var rep = errorSegment.GetField(1).Length; //append after existing reps if (SegmentName != null) { Terser.Set(errorSegment, 1, rep, 1, 1, SegmentName); } if (SegmentRepetition >= 0) { Terser.Set(errorSegment, 1, rep, 2, 1, Convert.ToString(SegmentRepetition)); } if (FieldPosition >= 0) { Terser.Set(errorSegment, 1, rep, 3, 1, Convert.ToString(FieldPosition)); } Terser.Set(errorSegment, 1, rep, 4, 1, Convert.ToString(ErrorCode)); // this replaces the need to connect to the database Terser.Set(errorSegment, 1, rep, 4, 2, ErrorCode.GetName()); Terser.Set(errorSegment, 1, rep, 4, 3, "hl70357"); Terser.Set(errorSegment, 1, rep, 4, 5, Message); }
public bool Match(IMessage message) { bool result = false; result = Compare(Hl7Version, message.Version); if (result) { // Dib0 20150125: Changed the compare. This method doesn't work with messages // that are parsed as generic messages //result = Compare(Structurename, message.GetStructureName()); Terser terser = new Terser(message); string messageType = string.Format("{0}_{1}", terser.Get("MSH-9-1"), terser.Get("MSH-9-2")); result = Compare(Structurename, messageType); } // Check the field filter if (result) { result = CheckFieldFilter(message); } return(result); }
/// <summary> Fills a field with values from an unparsed string representing the field. </summary> /// <param name="destinationField">the field Type /// </param> /// <param name="data">the field string (including all components and subcomponents; not including field delimiters) /// </param> /// <param name="encodingCharacters">the encoding characters used in the message /// </param> private static void Parse(IType destinationField, String data, EncodingCharacters encodingCharacters) { String[] components = Split(data, Convert.ToString(encodingCharacters.ComponentSeparator)); for (int i = 0; i < components.Length; i++) { int index = i + 1; if (components[i] != null && (Terser.isPrimitive(destinationField, index) && components[i].Contains(Convert.ToString(encodingCharacters.SubcomponentSeparator)))) { // sometimes someone sends us bad data and if the destinition is a primitive we should escape what needs to be escaped components[i] = Escape.escape(components[i], encodingCharacters); } String[] subcomponents = Split(components[i], Convert.ToString(encodingCharacters.SubcomponentSeparator)); for (int j = 0; j < subcomponents.Length; j++) { String val = subcomponents[j]; if (val != null) { val = Escape.unescape(val, encodingCharacters); } Terser.getPrimitive(destinationField, index, j + 1).Value = val; } } }
/// <summary> /// Create an Ack message based on a received message /// </summary> /// <param name="inboundMessage">received message</param> /// <param name="ackCode">Should be "AE" or "AR", can be "AA".</param> /// <param name="errorMessage">The reason the message was rejected or an error. If "AA" was supplied as ackCode the errorMessage should be null.</param> /// <returns>Created ACK message</returns> public static IMessage MakeACK(IMessage inboundMessage, string ackCode, string errorMessage) { IMessage ackMessage = null; // Get an object from the right ACK class string ackClassType = string.Format("NHapi.Model.V{0}.Message.ACK, NHapi.Model.V{0}", inboundMessage.Version.Remove(inboundMessage.Version.IndexOf('.'), 1)); Type x = Type.GetType(ackClassType); ackMessage = (IMessage)Activator.CreateInstance(x); Terser inboundTerser = new Terser(inboundMessage); ISegment inboundHeader = null; inboundHeader = inboundTerser.getSegment("MSH"); // Find the HL7 version of the inbound message: // string version = null; try { version = Terser.Get(inboundHeader, 12, 0, 1, 1); } catch (NHapi.Base.HL7Exception) { // I'm not happy to proceed if we can't identify the inbound // message version. throw new NHapi.Base.HL7Exception("Failed to get valid HL7 version from inbound MSH-12-1"); } // Create a Terser instance for the outbound message (the ACK). Terser terser = new Terser(ackMessage); // Populate outbound MSH fields using data from inbound message ISegment outHeader = (ISegment)terser.getSegment("MSH"); DeepCopy.copy(inboundHeader, outHeader); // Now set the message type, HL7 version number, acknowledgement code // and message control ID fields: string sendingApp = terser.Get("/MSH-3"); string sendingEnv = terser.Get("/MSH-4"); terser.Set("/MSH-3", CommunicationName); terser.Set("/MSH-4", EnvironmentIdentifier); terser.Set("/MSH-5", sendingApp); terser.Set("/MSH-6", sendingEnv); terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh")); terser.Set("/MSH-9", "ACK"); terser.Set("/MSH-12", version); terser.Set("/MSA-1", ackCode == null ? "AA" : ackCode); terser.Set("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1)); // Set error message if (errorMessage != null) { terser.Set("/ERR-7", errorMessage); } return(ackMessage); }
/// <summary> /// Create a PDQ search message /// </summary> /// <param name="filters">The parameters for query</param> private QBP_Q21 CreatePDQSearch(int offset, int count, object state, params KeyValuePair <String, String>[] filters) { // Search - Construct a v2 message this is found in IHE ITI TF-2:3.21 QBP_Q21 message = new QBP_Q21(); this.UpdateMSH(message.MSH, "QBP_Q21", "QBP", "Q22"); //message.MSH.VersionID.VersionID.Value = "2.3.1"; // Message query message.QPD.MessageQueryName.Identifier.Value = "Patient Demographics Query"; message.DSC.ContinuationPointer.Value = state?.ToString(); message.RCP.QuantityLimitedRequest.Quantity.Value = count.ToString(); message.RCP.QuantityLimitedRequest.Units.Identifier.Value = "RD"; // Sometimes it is easier to use a terser Terser terser = new Terser(message); terser.Set("/QPD-2", Guid.NewGuid().ToString()); // Tag of the query terser.Set("/QPD-1", "Patient Demographics Query"); // Name of the query for (int i = 0; i < filters.Length; i++) { terser.Set(String.Format("/QPD-3({0})-1", i), filters[i].Key); terser.Set(String.Format("/QPD-3({0})-2", i), filters[i].Value); } return(message); }
public void GetPrimitive_SubComponentIsLessThen0_ArgumentOutOfRangeException() { var type = suiS12.MSH.MessageType; Assert.Throws <ArgumentOutOfRangeException>( () => Terser.GetPrimitive(type, 0, -1)); }
public void Get_RepIsLessThan0_ThrowsArgumentOutOfRangeException() { var segment = suiS12.MSH; Assert.Throws <ArgumentOutOfRangeException>( () => Terser.Get(segment, 0, -1, 0, 0)); }
internal IHL7Message DoParse(IMessage message) { if (message == null) { throw new HL7apiException("Cannot parse an invalid message"); } IHL7Message ret = null; Terser t = new Terser(message); string messageID = t.Get("/MSH-21(0)-1-1"); if (string.IsNullOrEmpty(messageID)) { messageID = GetMessageIDFromMessageType(message.GetMessageType(), message.Version); if (string.IsNullOrEmpty(messageID)) { throw new HL7apiException("Invalid Message type"); } } ret = (IHL7Message)InstantiateMessage(messageID, message.Version, message); return(ret); }
/// <summary> /// Create a new instance of HL7Message /// </summary> /// <param name="message"></param> public HL7Message(IMessage message) { this.m_Message = message; this.m_HL7Parser = new HL7Parser(); this.m_Terser = new Terser(m_Message); this.m_MSH = m_Terser.getSegment("MSH"); }
/// <summary> /// Create NACK /// </summary> internal static IMessage CreateNack(IMessage request, string responseCode, string errCode, string errDescription, ISystemConfigurationService config) { System.Diagnostics.Trace.TraceWarning(String.Format("NACK Condition : {0}", errDescription)); if (request.Version == "2.3.1") { NHapi.Model.V231.Message.ACK ack = new NHapi.Model.V231.Message.ACK(); Terser terser = new Terser(ack); terser.Set("/MSA-1", responseCode); terser.Set("/MSA-3", "Error occurred"); terser.Set("/MSA-6-1", errCode); terser.Set("/MSA-6-2", errDescription); MessageUtil.UpdateMSH(terser, request, config); return(ack); } else { NHapi.Model.V25.Message.ACK ack = new NHapi.Model.V25.Message.ACK(); Terser terser = new Terser(ack); terser.Set("/MSA-1", responseCode); MessageUtil.UpdateMSH(terser, request, config); terser.Set("/ERR-3-1", errCode); terser.Set("/ERR-3-2", errDescription); return(ack); } }
/// <summary> /// Set request message parameters /// </summary> protected void SetRequestMessageParams(NHapi.Base.Model.IMessage request) { Terser setTerser = new Terser(request); setTerser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddHHmmss")); setTerser.Set("/EVN-2", DateTime.Today.ToString("yyyyMMdd")); }
/// <summary> Validates the given message. </summary> /// /// <exception cref="HL7Exception"> Thrown when a HL 7 error condition occurs. </exception> /// /// <param name="message"> a parsed message to validate (note that MSH-9-1 and MSH-9-2 must be /// valued) </param> /// /// <returns> true if the message is OK. </returns> public virtual bool validate(IMessage message) { Terser t = new Terser(message); IMessageRule[] rules = this.myContext.getMessageRules(message.Version, t.Get("MSH-9-1"), t.Get("MSH-9-2")); ValidationException toThrow = null; bool result = true; for (int i = 0; i < rules.Length; i++) { ValidationException[] ex = rules[i].test(message); for (int j = 0; j < ex.Length; j++) { result = false; ourLog.Error("Invalid message", ex[j]); if (this.failOnError && toThrow == null) { toThrow = ex[j]; } } } if (toThrow != null) { throw new HL7Exception("Invalid message", toThrow); } return(result); }
public void UnEscapesData() { // Arrange const string content = @"MSH|^~\&|TestSys|432^testsys practice|TEST||201402171537||MDM^T02|121906|P|2.3.1|||||||| OBX|1|TX|PROBLEM FOCUSED^PROBLEM FOCUSED^test|1|\T\#39;Thirty days have September,\X000d\April\X0A\June,\X0A\and November.\X0A\When short February is done,\E\X0A\E\all the rest have\T\nbsp;31.\T\#39"; var parser = new PipeParser(); var msg = parser.Parse(content); // Act var segment = msg.GetStructure("OBX") as ISegment; var idx = Terser.getIndices("OBX-5"); var segmentData = Terser.Get(segment, idx[0], idx[1], idx[2], idx[3]); // Assert // verify that data was properly unescaped by NHapi // \E\X0A\E\ should be escaped to \X0A\ // \X0A\ should be unescaped to \n // \X000d\ should be unescaped to \r // \t\ should be unescaped to & const string expectedResult = "'Thirty days have September,\rApril\nJune,\nand November.\nWhen short February is done,\\X0A\\all the rest have 31.'"; Assert.AreEqual(expectedResult, segmentData); }
/// <summary> /// Returns given <see cref="IType"/> as a pipe-encoded string, using the given encoding characters. /// <para> /// It is assumed that the Type represents a complete field rather than a component. /// </para> /// </summary> /// <param name="source">An <see cref="IType"/> object from which to construct an encoded string.</param> /// <param name="encodingChars">Encoding characters to be used.</param> /// <returns>The encoded type.</returns> /// <exception cref="HL7Exception">Thrown if the data fields in the group do not permit encoding (e.g. required fields are null).</exception> /// <exception cref="EncodingNotSupportedException">Thrown if the requested encoding is not supported by this parser.</exception> public static string Encode(IType source, EncodingCharacters encodingChars) { if (source is Varies) { var varies = (Varies)source; if (varies.Data != null) { source = varies.Data; } } var field = new StringBuilder(); for (var i = 1; i <= Terser.NumComponents(source); i++) { var comp = new StringBuilder(); for (var j = 1; j <= Terser.NumSubComponents(source, i); j++) { var p = Terser.GetPrimitive(source, i, j); comp.Append(EncodePrimitive(p, encodingChars)); comp.Append(encodingChars.SubcomponentSeparator); } field.Append(StripExtraDelimiters(comp.ToString(), encodingChars.SubcomponentSeparator)); field.Append(encodingChars.ComponentSeparator); } return(StripExtraDelimiters(field.ToString(), encodingChars.ComponentSeparator)); }
private EncodingCharacters GetValidEncodingCharacters(char fieldSep, ISegment msh) { var encCharString = Terser.Get(msh, 2, 0, 1, 1); if (encCharString == null) { // cdc: This was breaking when trying to construct a blank message, and there is no way to set the EncChars, so fill in a default // throw new HL7Exception("Can't encode message: MSH-2 (encoding characters) is missing"); encCharString = @"^~\&"; Terser.Set(msh, 2, 0, 1, 1, encCharString); } var version27 = "2.7"; if (string.CompareOrdinal(version27, msh.Message.Version) > 0 && encCharString.Length != 4) { throw new HL7Exception( $"Encoding characters (MSH-2) value '{encCharString}' invalid -- must be 4 characters", ErrorCode.DATA_TYPE_ERROR); } if (encCharString.Length != 4 && encCharString.Length != 5) { throw new HL7Exception( $"Encoding characters (MSH-2) value '{encCharString}' invalid -- must be 4 or 5 characters", ErrorCode.DATA_TYPE_ERROR); } return(new EncodingCharacters(fieldSep, encCharString)); }
public static String GetHL7Event(String message) { var parser = new NHapi.Base.Parser.PipeParser(); var parsedMessage = parser.Parse(message); //Terse it! Terser terser = new Terser(parsedMessage); //Grab RequiredFields string sEventType = terser.Get("/MSH-9-1"); string sMessageType = terser.Get("/MSH-9-2"); //Get the message type and trigger event var msgType = parsedMessage.GetStructureName(); //Console.WriteLine("msg type = {0}", sMessageType); // = ADT_EVENT //Get the message in raw, pipe-delimited format var pipeDelimitedMessage = parser.Encode(parsedMessage); //Console.WriteLine("msg = {0}", pipeDelimitedMessage); return(sMessageType); //msgType; //pipeDelimitedMessage; }
public void ProcessA01(string sHL7) { var parser = new NHapi.Base.Parser.PipeParser(); var parsedMessage = parser.Parse(sHL7); var a01 = parsedMessage as ADT_A01; string sPtName = ""; //Terser terser; Terser terser = new Terser(parsedMessage); sPtName = terser.Get("/PID-5"); string sFName = terser.Get("/PID-5-2"); string sLName = terser.Get("/PID-5-1"); //attempt parsing of a field that does not exist in transaction string sPatientID = terser.Get("/PID-1"); Console.WriteLine("Patient First Name = {0}", sFName); Console.WriteLine("Patient Last Name = {0}", sLName); //var patientMR = a01.PID.PatientID.IDNumber.Value; //var patientAcctNo= a01.PID.PatientAccountNumber.IDNumber.Value; //var patientName = a01.PID.GetPatientName(0); //string sLName = patientName.FamilyName.Surname.Value; //string sFName = patientName.GivenName.Value; //Console.WriteLine("Patient FName = {0}", sFName); }
/// <summary> /// Test /// </summary> /// <param name="msg"></param> /// <returns></returns> public override ValidationException[] test(NHapi.Base.Model.IMessage msg) { ValidationException[] result = new ValidationException[0]; foreach (MessageFieldMandatoryRuleElement rule in mandatoryRules) { bool flag1 = (rule.Version == "*") || (msg.Version == rule.Version); string structureName = msg.GetStructureName(); string[] sNames = structureName.Split('_'); bool flag2 = (rule.MessageType == "*") || (sNames[0] == rule.MessageType); bool flag3 = (rule.TriggerEvent == "*") || (sNames[1] == rule.TriggerEvent); if (flag1 && flag2 && flag3) { Terser terser = new Terser(msg); string value = terser.Get(rule.FieldIndicator); if (string.IsNullOrEmpty(value)) { result = new ValidationException[1] { new ValidationException(string.Format("Field '{1}' is mandatory.", value, rule.FieldIndicator)) }; } } if (result.Length > 0) { break; } } return(result); }
/// <summary> <p>Returns a minimal amount of data from a message string, including only the /// data needed to send a response to the remote system. This includes the /// following fields: /// <ul><li>field separator</li> /// <li>encoding characters</li> /// <li>processing ID</li> /// <li>message control ID</li></ul> /// This method is intended for use when there is an error parsing a message, /// (so the Message object is unavailable) but an error message must be sent /// back to the remote system including some of the information in the inbound /// message. This method parses only that required information, hopefully /// avoiding the condition that caused the original error. The other /// fields in the returned MSH segment are empty.</p> /// </summary> public override ISegment GetCriticalResponseData(String message) { //try to get MSH segment int locStartMSH = message.IndexOf("MSH"); if (locStartMSH < 0) { throw new HL7Exception("Couldn't find MSH segment in message: " + message, ErrorCode.SEGMENT_SEQUENCE_ERROR); } int locEndMSH = message.IndexOf('\r', locStartMSH + 1); if (locEndMSH < 0) { locEndMSH = message.Length; } String mshString = message.Substring(locStartMSH, (locEndMSH) - (locStartMSH)); //find out what the field separator is char fieldSep = mshString[3]; //get field array String[] fields = Split(mshString, Convert.ToString(fieldSep)); ISegment msh = null; try { //parse required fields String encChars = fields[1]; char compSep = encChars[0]; String messControlID = fields[9]; String[] procIDComps = Split(fields[10], Convert.ToString(compSep)); //fill MSH segment String version = "2.4"; //default try { version = GetVersion(message); } catch (Exception) { /* use the default */ } msh = MakeControlMSH(version, Factory); Terser.Set(msh, 1, 0, 1, 1, Convert.ToString(fieldSep)); Terser.Set(msh, 2, 0, 1, 1, encChars); Terser.Set(msh, 10, 0, 1, 1, messControlID); Terser.Set(msh, 11, 0, 1, 1, procIDComps[0]); } catch (Exception e) { SupportClass.WriteStackTrace(e, Console.Error); throw new HL7Exception( "Can't parse critical fields from MSH segment (" + e.GetType().FullName + ": " + e.Message + "): " + mshString, ErrorCode.REQUIRED_FIELD_MISSING); } return(msh); }
public static string GetMessageType(this IMessage message) { ISegment msh = (ISegment)message.GetStructure("MSH"); string messageType = $"{Terser.Get(msh, 9, 0, 1, 1)}" + $"_{Terser.Get(msh, 9, 0, 2, 1)}"; return(messageType); }
private static void TerserMessageHL7() { var stringMessage = File.ReadAllText( @"N:\hl7-master\hl7-master\Test HL7 Message Files\FileWithObservationResultMessage.txt"); // instantiate a PipeParser, which handles the normal HL7 encoding var pipeParser = new PipeParser(); // parse the message string into a message object var orderResultHl7Message = pipeParser.Parse(stringMessage); // create a terser object instance by wrapping it around the message object var terser = new Terser(orderResultHl7Message); var terserHelper = new TerserHelper(terser); var terserExpression = "/.MSH-6"; var dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"Field 6 of MSH segment using expression '{terserExpression}' was '{dataRetrieved}'"); terserExpression = "/.PID-5-2"; // notice the /. to indicate relative position to root node dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"Field 5 and Component 2 of the PID segment using expression '{terserExpression}' was {dataRetrieved}'"); terserExpression = "/.*ID-5-2"; dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"Field 5 and Component 2 of the PID segment using wildcard-based expression '{terserExpression}' was '{dataRetrieved}'"); terserExpression = "/.P?D-5-2"; dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"Field 5 and Component 2 of the PID segment using another wildcard-based expression '{terserExpression}' was '{dataRetrieved}'"); terserExpression = "/.PV1-9(1)"; // note: field repetitions are zero-indexed dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"2nd repetition of Field 9 and Component 1 for it in the PV1 segment using expression '{terserExpression}' was '{dataRetrieved}'"); terserExpression = "/RESPONSE/PATIENT/PID-5-1"; dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"Terser expression '{terserExpression}' yielded '{dataRetrieved}'"); terserExpression = "/RESPONSE/PATIENT/VISIT/PV1-9-3"; dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"Terser expression '{terserExpression}' yielded '{dataRetrieved}'"); terserExpression = "/RESPONSE/ORDER_OBSERVATION(0)/ORC-12-3"; dataRetrieved = terserHelper.GetData(terserExpression); LogToDebugConsole($"Terser expression '{terserExpression}' yielded '{dataRetrieved}'"); //let us now try a set operation using the terser terserExpression = "/.OBSERVATION(0)/NTE-3"; terserHelper.SetData(terserExpression, "This is our override value using the setter"); LogToDebugConsole("Set the data for second repetition of the NTE segment and its Third field.."); LogToDebugConsole("\nWill display our modified message below \n"); LogToDebugConsole(pipeParser.Encode(orderResultHl7Message)); }