Splitting stream into HL7 messages
Hi,
I want to consume an API that provides HL7 messages. To achieve this, I have thought of the following workflow:
I have created a business service that periodically triggers a business process. The trigger request is forwarded to a business operation. There, a %Net.HttpRequest is assembled from scratch and then sent to the API endpoint. The corresponding HttpResponse then contains several HL7 messages encoded in UTF-8 in the message body. To further process the HL7 messages, the operation sends the HttpResponse back to the business process as EnsLib.HTTP.GenericMessage.
The raw data looks like this:
MSH|^~\&|Doctolib||Doctolib||20251028154100||SIU^S12|d50f01e649cda79faf29|P|2.5.1|||||FRA|UTF-8
SCH||20771389^Doctolib||||Vor.Tagesk^Vorgespräch für Tagesklinik|||||^^15^202511101000|||||117134^Mustermann^Stefan||||Doctolib|||||Booked
NTE|||Hier der Inhalt des Notizfeldes. Achten Sie auf Umlaute: ä ö ü (UTF-8)
PID|||56834111^^^Doctolib^PI||Testfrau^Liselotte^^^^^L||19690722|F|||||+4917612345678^^^liselotte@test.de~+4940123456
RGS|1
AIG|1|||Vorg-Tagesklinik^Vorgespräche Tagesklinik
MSH|^~\&|Doctolib||Doctolib||20251028154114||SIU^S13|39e482e10fa61ccd4500|P|2.5.1|||||FRA|UTF-8
SCH||20771389^Doctolib||||Vor.Tagesk^Vorgespräch für Tagesklinik|||||^^15^202511141600|||||117134^Mustermann^Stefan||||Doctolib|||||Booked
NTE|||Hier der Inhalt des Notizfeldes. Achten Sie auf Umlaute: ä ö ü (UTF-8)
PID|||56834111^^^Doctolib^PI||Testfrau^Liselotte^^^^^L||19690722|F|||||+4917612345678^^^liselotte@test.de~+4940123456
RGS|1
AIG|1|||Vorg-Tagesklinik^Vorgespräche Tagesklinik
MSH|^~\&|Doctolib||Doctolib||20251028154225||SIU^S17|1e5726345c7b4257b41f|P|2.5.1|||||FRA|UTF-8
SCH||20771388^Doctolib||||Vor.Tagesk^Vorgespräch für Tagesklinik|||||^^15^202511121600|||||117134^Mustermann^Stefan||||Doctolib|||||Deleted
NTE|||Hier der Inhalt des Notizfeldes
PID|||56834102^^^Doctolib^PI||Testmann^Heinrich^^^^^L||19881211|M|||||+4917612345678^^^heinrich@test.de~+4940123456
RGS|1
AIG|1|||Vorg-Tagesklinik^Vorgespräche Tagesklinik
The next step would be to split the message body into individual HL7 messages and then forward them accordingly. But splitting them up is causing me problems. In the message viewer, the stream is still displayed with line breaks. First, I tried to read the stream line by line and then save the individual streams in a collection (%ListOfObjects). However, the line breaks seem to get lost in the process.
Then I tried to save it in a collection of strings using the string “MSH|” (the start of the message) to split the stream. That worked, but unfortunately there were problems when converting the string to an EnsLib.HL7.Message because the framing did not fit.
How would you go about turning a stream with multiple HL7 messages into individual HL7 messages?
Regards
Robert
Comments
To split a stream containing multiple HL7 messages into individual HL7 messages, you can follow these summarized steps that are extracted from different documented approaches:
Identify Starting Points of HL7 Messages: Use the
MSH|segment as a delimiter to identify individual HL7 messages. This can be accomplished by scanning the stream for each occurrence ofMSH|and ensuring each message starts from there.Stream Handling:
- First, read the entire input stream containing the series of HL7 messages.
- Loop through the content, splitting it at every occurrence of the
MSH|delimiter. - For this, you might store each message as an individual string or an EnsLib.HL7.Message object in a collection (such as a list or array) for further processing.
Create HL7 Messages:
- After extracting segments based on delimiters, instantiate new HL7 message objects using the raw content you have extracted.
- Set the properties and ensure the framing is correct for each message object.
Use Business Processes or ObjectScript Logic:
- You can write ObjectScript logic to loop through the stream, parse out each HL7 message, and process or route it. Ensure that the formatting remains compliant with HL7 standards before routing.
Save or Forward Messages:
- Process these individual messages as required within the production (e.g., store in EnsLib.Message or forward them to other components in your InterSystems setup).
For implementing the splitting process more programmatically, you can use InterSystems ObjectScript or related tools such as DTLs for message transformation or splitting logic.
Consider efficiently using InterSystems features for handling streams and HL7 messages, and ensure to test with various configurations to verify the messages stay HL7-compliant after splitting [1][2][3].
Sources:
What's the line (segment) delimiter used in the stream? Maybe (likely?) $c(10), there maybe a message delimiter.
My suggestion is to save the stream into a file and then using an hex editor check what your stream actually contains and how is delimited.
Then, with this accurate info, you can split your stream in HL7 messages.
Check ParseIOStream/ParseFramedIOStream from EnsLib.HL7.Parser. These methods take a stream (read to a specific position) and return next HL7 message. Overall loop can be seen in EnsLib.HL7.Service.FileService's OnProcessInput.