You are here: Jython Script Interfaces > Jython Code Samples for the Datamapper

Jython samples for datamapping scripts

 

(A complete API definition for Jython in datamapping scripts is here.)

Basic string operations

 

To pass through the input value to the output, you can leave the Jython code area blank, or write:

output = input

To output the constant string 'A01', regardless of the input: 

output = 'A01'

Take the first 5 characters from the input and use that as the output (this will turn 'ID12345' into 'ID123'):

output = input[:5]

Take the 6th and subsequent characters (this will turn 'ID12345' into '45'):

output = input[5:]

To output the 3rd through the 5th characters of the input (this will turn 'ID12345' into '123'):

output = input[3:6]

Use the last 5 characters (turning 'ID12345' into '12345'):

output = input[-5:]

To output only the first character (turning 'ID12345' into 'I'):

output = input[0]

Output only the fourth character ('2'):

output = input[3]

Output the first two characters, followed by an underscore, followed by the third, followed by the fifth character through to the end (turning 'ID12345' into 'ID_1345'):

output = input[:2] + '_' + input[3] + input[5:]

Add a prefix (turning 'ID12345' into 'DEVID12345'):

output = 'DEV'+input

To convert all letters to lower case (turns 'ID12345' into 'id12345'): 

output = input.lower()

To convert all letters to upper case (turns 'id12345' into 'ID12345'): 

output = input.upper()

Replace all dashes with underscores (turns 'ID-12-34-5' into 'ID_12_34_5'): 

output = input.replace('-', '_')

Remove all dashes (turns 'ID-12-34-5' into 'ID12345'): 

output = input.replace('-', '')

Remove the string 'ID' (turns 'ID-12-34-5' into 'ID12345'): 

output = input.replace('ID', '')

 

"if" conditions

 

Output one value if the length of the input is 5 characters or less, and another value otherwise:

if len(input) <= 5:
output = 'X'
else:
output = 'Y'

Output certain values based on whether the input starts with certain strings:

if input.startswith('MSG'):
output = 'Type 1'
elif input.startswith('ADT'):
output = 'Type 2'
else:
output = 'other'

Regular expressions

 

To output different values based on whether the input matches a pattern (AKA regular expression). In this example, we are looking for an 8-digit date in YYYYMMDD format:

import re
if re.match(r'^\d{8}$', input):
output = input
else:
output = 'NO DATE FOUND'

In this case if the input is for example '20140101' or '19900813' then the output will be the same. If the input is not 8 digits - for example '2014', '201401011200', 'JOHN DOE' - then the output will be 'NO DATE'.

The ^ in this pattern matches the beginning of the string. The $ matches the end of it. \d matches a digit (0 to 9) and {8} matches 8 of them. See here for more information on regular expression syntax.

 

Normalize whitespace - that is, replace all runs of one or more space characters with a single space character (turns '    ID   12   3   4   5    ' into ' ID 12 34 5 '): 

import re
output = re.sub(' +', ' ', input)

Normalize whitespace and also remove all leading and trailing spaces (turns '    ID   12   3   4   5    ' into 'ID 12 34 5'): 

import re
output = re.sub(' +', ' ', input)
output = output.strip()

Remove all numbers (turns '123-AB' into '-AB'): 

import re
output = re.sub(r'\d', '', input) 

Remove all non-number characters (turns '123-AB' into '123'): 

import re
output = re.sub(r'[^\d]', '', input) 

Remove all letters (turns '123-AB' into '123-'): 

import re
output = re.sub(r'[a-zA-Z]', '', input)

Remove all non-letter characters (turns '123-AB' into 'AB'): 

import re
output = re.sub(r'[^a-zA-Z]', '', input)

 

Taking actions other than simple string output

 

To take more drastic action if the input value is not 8 digits, there are several options available.

To log an INFO-level message, in addition to outputting the value of 'NO DATE':

import re
if re.match(r'^\d{8}$', input):
output = input
else:
print 'No date found.'
output = 'NO DATE FOUND'

To log a WARNING-level message:

import re
if re.match(r'^\d{8}$', input):
output = input
else:
print >> engine.logwarn, 'No date found.'
output = 'NO DATE FOUND'

To cancel the execution (that is, prevent this task and downstream tasks from executing in response to this message):

import re
if re.match(r'^\d{8}$', input):
output = input
else:
engine.cancel()

To fail the execution (like a cancel, but also logs an error message and might send an alert e-mail):

import re
if re.match(r'^\d{8}$', input):
output = input
else:
engine.fail()

To also print a log message depending on the 'year' part of the 8-digit date:

import re
if re.match(r'^\d{8}$', input):
year = int(input[:4])
if year < 1980:
print 'Patient was born before 1980'
else:
print 'Patient was born during or after 1980'
output = input
else:
engine.fail()

 

util functions:

 

Assuming that the input date matches the format YYYYMMDD, to set the output to the input plus 30 days:

output = util.addToDate(input, 'DAY', 30)

Output the current time: 

output = util.getCurrentDateTime('yyyy-MM-dd HH:mm:ss.SSS')

Variables

 

To output the value of the variables with the name 'messagetype':

output = var('messagetype')

 

Beyond simple string input - getting input from other parts of the source document

 

You could define a script such as the following on MSH.10-Message_Control_ID to add to the input value a prefix that consists of the 'sending application' and 'receiving application' field values:

sendingapp = input('../MSH.3-Sending_Application/HD.1-Namespace_ID')
receivingapp = input('../MSH.5-Receiving_Application/HD.1-Namespace_ID')
output = sendingapp + receivingapp + input

The above example uses a relative path, starting with '..'. You can also use an absolute path, starting with '/'. The code below will do the same thing as the code above.

sendingapp = input('/resources/ADT_A01/MSH/MSH.3-Sending_Application/HD.1-Namespace_ID')
receivingapp = input('/resources/ADT_A01/MSH/MSH.5-Receiving_Application/HD.1-Namespace_ID')
output = sendingapp + receivingapp + input

Note that you can get the absolute path of any node in the source tree by clicking on it's node on the left-hand side of the datamapping tree view, and selecting 'Copy node path to clipboard'.

 

Looping over input values using the inputs() function, to output the first value that starts with 'ID'

 

This code assumes that your HL7 structure has a PID segment with a PID.3-Patient_Identifier_List child with an unlimited maximum cardinality, which in turn has a CX.1-ID_Number which has a maximum cardinality of 1. Also, that the source PID is mapped to the destination PID, source PID.3 to destination PID.3 etc., and that this script is defined on the mapping for CX.1-ID_Number.)

 

for inputval in inputs('../../PID.3-Patient_Identifier_List/CX.1-ID_Number'):
if inputval.startswith('ID'):
output = inputval
break

 

Beyond simple string output - outputting an XML sub-tree

 

You can output multiple sub-elements in a single script. For example, if the element 'MSH.3-Sending_Application' has three components under it, you could write the following script on 'MSH.3-Sending_Application':

 

outputxml('HD.1-Namespace_ID', 'MDLINK')
outputxml('HD.2-Universal_ID', '7b8a9679-8f60-4c88-b4e7-61d4a50c62a2')
outputxml('HD.3-Universal_ID_Type', 'UUID')