Skip to Content
Technical Articles
Author's profile photo Raul Vega

XML <-> HL7 Converter using Groovy script (Integration Suite) and external libraries

Hello my name is Raúl and I am passionate about SAP Integrations.

In this blog, my first one, I am going to show you an easy way for converting from XML to HL7 and vice versa. Hopefully it results useful whether you are migrating some integration form PI/PO to Integration Suite.

Nowadays in the Converters menu there is no a XML <-> HL7 option, so let’s go!

Converter%20options Converter available options

 

First of all, we have to download the Hapibase library (hapi-dist-2.2-all.zip) from the following link: https://sourceforge.net/projects/hl7api/files/hl7api/2.2/

They have a lot of interesting code examples, FAQs, mailing list, etc…

 

Once you have downloaded the file, add it to the Resources:

Files%20uploaded%20to%20Resources

Files uploaded to Resources

 

Ok, now the hard work is done… only remains to choose one option: convert from XML to HL7 (A) or from HL7 to XML (B).

 

A) XML to HL7

As it is just an educational blog, let’s do it simple, just 2 steps…

  • First step is a Content Modifier, it is needed because the original namespace of the xml have to be replaced with “urn:hl7-org:v2xml” so we create a property called input_namespace and externalize it to change it easily (replacement is made in the next step).

Namespace%20Exception

  • Second step is the Groovy script. It is really simple… get body, clean body, parser and encode body and set the enconded body (or the exception) to the message.
import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.parser.GenericParser;
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;

def Message processData(Message message) {
    
    def String body_enconded = "";
    def body = message.getBody(java.lang.String);
    
    //Instantiate parser
    HapiContext context = new DefaultHapiContext();
    GenericParser parser = new GenericParser(context);

          try {
            
            //First clean the XML
            body = cleanXML(body, message);
            //and then parse method performs the actual parsing & encoding
            ca.uhn.hl7v2.model.Message msg = parser.parse(body);
            body_enconded = parser.encode(msg);
              
          } catch (EncodingNotSupportedException e) {
            body_enconded =  "EncodingNotSupportedException: " + e.toString();
          } catch (HL7Exception e) {
            body_enconded = "HL7Exception: " + e.toString();
          }
    
    message.setBody(body_enconded);
    return message;
    
}

def java.lang.String cleanXML(java.lang.String xml_str, Message message) {       
    
    //get externalized parameter and replace it
    def map = message.getProperties();
    def String input_namespace = map.get("input_namespace");
    
    xml_str = xml_str.replaceAll("<", "<");
    xml_str = xml_str.replaceAll(">", ">");
    xml_str = xml_str.replaceAll("&", "&");
    xml_str = xml_str.replaceAll("<n0:", "<");
    xml_str = xml_str.replaceAll("</n0:", "</");
    xml_str = xml_str.replaceAll(input_namespace, "urn:hl7-org:v2xml");
    xml_str = xml_str.replaceAll("xmlns:n0=\"urn:hl7-org:v2xml\"", "xmlns=\"urn:hl7-org:v2xml\"");
    return xml_str;
    
}

 

Catching exceptions are useful and give us clues as to what might be going wrong, i.e.:

 

So let’s try our scenario by doing a Simulation:

Test%20body%20payload

Test body payload

 

Result%20body%20encoded

Result body encoded

 

B) HL7 to XML

In this case, only have one step because no namespace replacement is needed prior the encoding and XML modification after the encoding is not the goal of the blog.

 

Groovy script looks like this:

import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.parser.PipeParser;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
import ca.uhn.hl7v2.parser.XMLParser;
import ca.uhn.hl7v2.parser.DefaultXMLParser;
import com.sap.gateway.ip.core.customdev.util.Message;

def Message processData(Message message) {
    
    //Body
    def java.lang.String body = message.getBody(java.lang.String);

    def java.lang.String XML = "";
    HapiContext context = new DefaultHapiContext();    
    XMLParser xmlParser = (XMLParser)new DefaultXMLParser();
    PipeParser pipeParser = new PipeParser();
 
    try {
    // The parse method performs the actual parsing
    XML = xmlParser.encode(pipeParser.parse(body));   

    } catch (EncodingNotSupportedException e) {
        XML =  "EncodingNotSupportedException: " + e.toString();
    } catch (HL7Exception e) {
        XML = "HL7Exception: " + e.toString();
    } 
    
    message.setBody(XML);
    return message;
}

 

The tricky part here is that payload needs a HL7 segment separator (\r = Carriage return) at the end of every segment. So, for testing purpose I create a file with Mac linebreaks.

 

Testing HL7 payload:

 

Encoded body in xml:

 

Thanks for reading my first blog! I hope it was worth getting here. Any comment or feedback will be welcome.

Hasta pronto, Raúl.

Assigned Tags

      5 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Ryan Crosby
      Ryan Crosby

      Nice work!  I had previously done something similar in PO (with the same library) at a previous job for a case where we were using HL7 messages.  You gave me mild nightmares though because the original work was done in an older environment with different libraries, and they had modified the standard, so I had to retrofit the XSDs in the HAPI stuff.

      Author's profile photo Ahmad Shaik
      Ahmad Shaik

      Hi Raul Vega,

      Thanks for the details blog for H7 converters..

      Author's profile photo Alberto Pla Alcojor
      Alberto Pla Alcojor

      Great work Raul! Very Useful.

      Author's profile photo Avinash Paul Ullamparhti
      Avinash Paul Ullamparhti

      Thank you for the Blog

      Author's profile photo Wilson Xavier
      Wilson Xavier

      Congratulations! Thank you so much!