› Clovertech Forums › Read Only Archives › Cloverleaf › Cloverleaf › Replacing an ampersand with T
We’re trying to replace an ampersand with T on OBX5 within the XLT using:
set xlateOutVals
]]
It’s not working – seems to be ignoring the tcl because of the &. The string map works if we test using a different character – but it doesn’t seem to like the ampersand. I searched through clovertech and found some references from others, but I’m still not clear whether or not we can replace the & from within a XLT and just are doing it incorrectly -or- does this need to be done in a tcl proc on the inbound TPS?
Appreciate your help!
Jeanne Cole
GE Healthcare
Jeanne,
When you reference that field in the Xlate the parse stops at the sub-component (in this case the &) if it exists unless you use sub-component notation. But even then you won’t actually get the subcomponent separator.
There are 2 ways to solve this that I see.
1. Have the source system follow the standard and use the standard defined encapsulation for you (then you don’t have to do anything and amazingly the source system can probably be somewhat truthful when it states it is HL/7 compliant).
2. Use Tcl either at the Inbound Tps (I would not do it here); or pre-Xlate; or post Xlate; or the Outbound TPS. If your issue is to relieve the Xlate of the effects of the subcomponent separator as text then the pre-Xlate context is probably the best.
Just make sure you write your proc to use the MSH-2 subcomponent character rather than hardcoding the & (then your proc can be used for the next vendor that cannot follow the standard and might use a different subcomponent character).
Of course this is all assuming the receiving system can change the T back appropriately 😆
Some folks have also fooled around with setting the MSH-2 characters to supposedly non-enterable characters – but my opinion is that bandaid is a time bomb waiting to go off.
email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.
I have a similar situation but have pre-fixed the ampersand with an escape character for testing purposes. However I
Dave,
Use of the escape character without using the proper set does not obviate the effect of the separator.
For example & – the & is still a separator and unless in the Xlate you use the propers sub-component notation, parsing will stop with the separator (& in this case).
The proper way to do this is to change the & to T as is described in the HL/7 standard (there are other patterns for the other separators as well).
No more work is necessary assuming the receiving systems will change the T back to &.
If it will not, then you can have a Tcl proc post Xlate (maybe at the outbound TPS) to change that back – but then the question is will the receiving system choke on the mal placed separator?
email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.
Thanks Jim,
The scales are once again lifted from my eyes. In this case the receiving system will not care as it’s a csv file.
Dave,
Lucky you!!
email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.
Not sure if this will help but we have the proc in a few places. You can change whatever you need if it fits your needs.
#######################################################################################
#######################################################################################
#######################################################################################
#
# Name: tpsFixAmpersand.tps
# Purpose: This procedure fixes messages with the special character “&” in them.
# This was needed because messages from affinity going to INPC had the
# “&” in the message and it would mess up their feed.
# The messages will now be fixed.
# If the “&” is the last character in a field or subfield, it is deleted.
# If it is in the middle of the field, it is replaced with a “-“
#
#
# UPoC type: tps
# Args: tps keyedlist containing the following keys:
# MODE run mode (“start”, “run” or “time”)
# MSGID message handle
# ARGS user-supplied arguments:
#
# Returns: tps disposition list:
#
# John Zalesak 01-08-2009
# Created
#
# John Zalesak 01-15-2009
# Modified message in engine log so we can see it better
#
#
#######################################################################################
#######################################################################################
#######################################################################################
proc tpsFixAmpersand { args } {
#######################################################################################
# Setup some globals used
#######################################################################################
global HciConnName
global HciRoot
global HciSite
#######################################################################################
# Get the Connection Name for Error/Debug Messages
#######################################################################################
set myname “$HciSite/$HciConnName/[lindex [info level 1] 0]”
#######################################################################################
# Initialize Variables Used
#######################################################################################
set dispList {} ;# Disposition List Returned to Engine
set badchar & ;# Bad Character to Look for
set charloc 0 ;# Location of offending character
set nextloc 0 ;# Location of Char after bad char
set newchar “” ;# Replace bad char with this
#######################################################################################
# Load in the arguments we need that were passed from the caller
#######################################################################################
keylget args MODE mode ;# The mode the engine called from
#######################################################################################
# We only want to take action if called from the run mode
#######################################################################################
switch -exact — $mode {
start { }
run {
set mh [keylget args MSGID] ;# Get message handle from args
set dispList
set msg [msgget $mh] ;# Get a copy of the message
set fldSep [string index $msg 3] ;# Field Seperator
set subSep [string index $msg 4] ;# Sub-Field Seperator
set repSep [string index $msg 5] ;# Repeating Field Seperator
#######################################################################################
# Search for “&” and if found correct
# Start at location 8 to get past field seperator definitions
#######################################################################################
while {[set charloc [string first $badchar $msg 8]] != -1} {
set nextchar [string index $msg [expr $charloc + 1]]
switch -exact — $nextchar
$fldSep –
$subSep –
$repSep –
“r” {set newchar “”}
default {set newchar “+”}
# echo “:WARN “
# echo “:WARN
# echo “:WARN $badchar character found going to infinity at location $charloc”
# echo “:WARN Here is $myname”
# echo “:WARN Now is [clock format [clock scan now] -format “%D – %T”]”
# echo “:WARN Original Message shown below”
# echo $msg
# echo “:WARN
# echo “:WARN ”
set msg [string replace $msg $charloc $charloc $newchar]
}
msgset $mh $msg
}
time { }
shutdown { }
} ;# End Switch
return $dispList
} ;# End Proc
There may be a way to handle the & in an Xlate, but it takes a couple of steps. We had something similar in our case except the vendor included & as part of the data for address field, and we could not get them to change. Here is what we did.
CONCAT OBX.5 to a variable, e.g., @field, and specify T as your separator. This picks up all the sub components.
COPY @field to the destination.
Hope this helps,
Robert Milfajt
Northwestern Medicine
Chicago, IL
Robert,
Very interesting.
I just experimented with that and eliminated the temp variable (I CONCATenated directly to the outbound field) and that seems to have worked as well.
Thanks!!
email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.
I tried it both ways and for OBR.15 |SSE&Serum (sendaway)&L^^^&&| I’m getting SSE T
I was asked to attempt this in an xlate some time ago, and it was before all the cool kids were using string map.
Dave,
That is because yours is a multiple component field and Robert’s was not.
In your case, you would need to do the CONCAT with each component rather than at the field level.
email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.
Vince,
I am not sure that works in an Xlate as the xlateInVals value will be truncated at the sub-component separator so the regsub will be against an already truncated field and never see the sub_component to replace.
The regsub or string map will work at the TPS or pre-Xlate level against the whole message – but what if there realy are valid sub-component separators in the message – won’t those get escaped as well (they should not be)?
email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.
Good point, Jim — I should’ve put in the caveat that I was working from memory and the tclshell. I’m thinking that I pulled the field from a higher tier in the path so that I got all the subcomponents and of course, treat the values as a list as well. Thanks for catching me on that…
Robert/Jim,
The solution does work for me. I’ve just noticed my outbound field was set to 6 chars. I set it to -1 and I’m seeing the whole thing now
Just having a cup of tea with a slice of humble pie.
🙄