This concludes the making of all segments that make up the message. At this point it is interesting to check on Perl's internal representation of our message:
Despite completing the message, our job is not done yet, as we have to make sure that the message conforms to the specifications; and we're going to do that over the Internet by calling into a validation service.
IHE Gazelle HL7 Validator is a web service that accepts XML SOAP messages over HTTP. The service accepts messages that adhere to an HL7 conformance profile (a description of the data and messages that an interface sends and/or receives) using a profile OID. The XML packet should also contain our raw HL7 message.
The service replies with the errors found, so we just have to keep resubmitting until we eliminate them all, at which point we are rest assured that we achieved full conformance.
Unfortunately the OID's available, apply to v2.5 only so our 2.6 message will be validated against 2.5 specs, something that is certain to result in errors. Nevertheless, validation aside, we will go through with the example to also demonstrate how a SOAP web service is accessed, but won't get into further details; we save them for another part of the article on parsing HL7 CDA's with XML::Twig.
So, the web service API offers two methods:
validate(): validates the given message against the given profiles and sends back a validation report
about(): gives information about the running version of the tool
The definition of the web service API is available here and describes its validate() method with the following prototype:
public String validate(String, String, String) throws SOAPException;
The first parameter is xmlValidationMetadata, it is an XML formatted String respecting the XSD schema given at http://gazelle.ihe.net/xsd/MessageMetadata.xsd. This parameter is optional.
The second parameter is xmlValidationContext, it is an XML formatted String respecting the XSD schema given at https://gazelle.ihe.net/xsd/ValidationContext.xsd. This parameter is mandatory since it gives information about the HL7 message profile to use for the validation process.
Finally, the third String stands for the message to validate. The message must use ER7 syntax (i.e.. pipe-based syntax)
To cut the story short, we need to call the validate() method with a complex XML validateMessage type that is broken down to three String primitives:
xmlValidationMetadata type is optional so we will skip it.
As the method expects a string, xmlValidationContext type will point to the strignified version of the ValidationContext XML complex type whose definition can be found in 'ValidationContext.xsd'.
messageToValidate will point to our raw HL7 message.
By comparison, the Perl code to to construct the appropriate structure as well as to call the service is:
use XML::Compile::SOAP::Trace; use XML::Compile::WSDL11; use XML::Compile::SOAP11; use XML::Compile::Transport::SOAPHTTP; use XML::Compile::SOAP::Trace ; use XML::LibXML; use strict;
my $wsdl = XML::Compile::WSDL11->new("gazelleHL7v2ValidationWS.wsdl"); $wsdl->importDefinitions("ValidationContext.xsd");
my $schema = XML::Compile::Schema->new("ValidationContext.xsd"); my $doc = XML::LibXML::Document->new('1.0', 'UTF-8'); my $write = $schema->compile(WRITER =>'ValidationContext'); my $xml = $write->($doc, $validate);
$doc->setDocumentElement($xml);
my $finalstuct ={ xmlValidationMetadata=>'', xmlValidationContext=>"$doc", messageToValidate=>$message };
my $call = $wsdl->compileClient('validateMessage');
my ($response, $trace) = $call->($final,'UTF-8');
The service responds with another XML message whose important parts are highlighted below:
The NrOfValidatedAssertions are those passing the test, while the errors that occurred are due to the difference in the HL7 versions. Such errors are:
<Error> <Location>ADT_A01/MSH[0]/MSH-3(Sending Application)</Location> <Description>Element \'Sending Application\' is specified as required (R) but not present in the message</Description> <Type>Required field missing</Type> </Error>
<Error> <Location>ADT_A01/MSH[0]/MSH-4(Sending Facility)</Location> <Description>Element \'Sending Facility\' is specified as required (R) but not present in the message</Description> <Type>Required field missing</Type> </Error>
<Error> <Location>ADT_A01/EVN</Location> <Description>Element \'EVN\' is specified as required (R) but not present in the message</Description> <Type>Segment sequence error</Type> </Error>
Let's pick the error related to the EVN segment as an example. EVN indicates the event that happened (in this case the admission of the patient) hence it contains information about the type of the message, but because it duplicates information found in the MSH such as "A01" it was removed from version 2.3 onwards; nevertheless the specific OID profile requires it, so we have to set it. Following all the guidelines we finally restructure the message into:
Validation is one thing, but connecting to a receiving interface and exchange messages, is another. The receiving end will typically respond with an 'acknowledgement' message. If the operation is successful:
Hl7 messages were mostly exchanged over TCP/IP with the client and the server opening a socket to communicate. The most popular communication protocol for the client and server to talk to each other is the so called Lower Layer Protocol (LLP) but HL7 messages can also be send via a variety of TCP/IP transports, like FTP, SOAP and SMTP.
LLP uses special block markers at the start, <SB> or 0x0b, and the end, <EB> or 0x1c, of every HL7 message, followed by a carriage return <CR>: <SB> <HL7 message> <EB><CR>
The receiver then strips those markers to get at the pure message.
Things have evolved though so that we now can have HL7 over HTTP.
HL7 over HTTP is intended as a transport level protocol for transactional messaging between systems and is intended as an alternative to the traditional Minimal Lower Layer Protocol (MLLP). It provides a number of key improvements:
HTTP is widely used for a variety of purposes, and is well understood by application developers, network engineers, etc.
HTTP allows for authentication (username/password) and character set encoding to be specified in a standardized way.
Tool and hardware support for HTTP is widespread, with many specialized software and hardware devices providing enhanced support for common protocols such as HTTP. In addition, HTTP is widely supported on many platforms, and may be viewed as a "commodity-level" feature. Many languages and toolsets have built in support for HTTP.
This brings forward the issue of the character set used in the communication. What does HL7 use? The specs are pretty clear on that :
"HL7 doesn't have its own character set. It has a mechanism for escaping multibyte characters, this is mainly/only used by systems that would otherwise mangle a multibyte character (e.g. lots of US 7-bit ASCII systems). UTF-8 is the de-facto standard encoding for v2 messages in North America, in Europe it's ISO 8859-1 (Latin-1). UTF-8 is the commonly used encoding for UNICODE. Note that UNICODE is an example of a character set, it is not a character encoding. Use "UNICODE UTF-8" in MSH.18 and you're all set. See UNICODE FAQ for details about UNICODE and its encodings (UTF-8, UTF-16, UTF-32)
Note: HL7 2.x versions prior to version 2.8 indicated that any of the UNICODE encodings are acceptable in the HL7 messages. After some practical experience with using UNICODE, it was determined that only UTF-8 can be safely used as a UNICODE encoding in HL7 messages and as of HL7 version 2.8 only UTF-8 is listed as an allowed encoding. This applies to earlier versions of HL7 messages as well: in order to insure interoperability, UTF-16 or UTF-32 SHALL NOT BE USED IN HL7 v2.x messages.
Hints: Try to avoid using operating system specific character pages (e.g. Windows cp1252, Mac code pages, EBCDIC variations)"
Conclusion
The standard is constantly evolving, as such version 3, CDA, and subsequently FHIR, work with XML messages. Their use is not as widespread as HL7 v2.x though, which occupies 95% of US Health institutions and about the same percentages throughout the world. Therefore having knowledge of HL7 v2.x is, and will be for many years to come, a well sought out skill in the HealthIT industry.
The source code for the examples can be found on Pastebin:
The US National Institute of Standards and Technology (NIST) has issued the second public draft of the proposed new version of its Digital Identity Guidelines. It includes updated rules [ ... ]
The Royal Swedish Academy of Sciences has awarded a half share of the 2024 Nobel Prize For Chemistry to Demis Hassabis, CEO of Google DeepMind and his colleague John Jumper for "protein stru [ ... ]