› Clovertech Forums › Read Only Archives › Cloverleaf › Tcl Library › pulling certain section of xml
This is just a straight raw route so i’m just using tcl.
===Follow-Up Appointment====
Thanks for any insight.
Oh the XML woes.
I fight with this type of stuff on and off.
There are a number of different ways to do this and none are really great. You can use regexp to pull information. Depending on how big the CCD is, that may not be what you want. You could write a program to split up the Tagname and put them into a keyed list and then pull out the information from there. You could write a loop to find the beginning and ending of but this would fail if your data has more than one section of .
Dealers choice.
Rob
Same here. I use simple, crude text parsing to pick my way through the Discharge Instructions. I’l bet each EMR formats them differently.
# get Discharge Instructions text from CCDA
set textDI [parseString “2.16.840.1.113883.10.20.22.2.41” “” “” 1 “$xml”]
# get first followup to start the loop
set start 0
set followup [get_next_follow_up_visit $debug “$textDI” $start]
lassign [split “$followup” “|”] code provider address msi start
if {$code > 4} {set dispList [return_error $debug $module $mh “$provider”] ; return $dispList}
# looping through referrals – if and while there are more referrals, process each one
while {$code 4} {set dispList [return_error $debug $module $mh “$provider”] ; return $dispList}
}
Where the –
– textDI is a code used to indicate the Discharge Instructions
– provider is the doctor name that will be used to do a table lookup to get the Direct email address
– address is a physical address, just to provide a second data element to use in the provider lookup, to make sure we have a unique doctor
– msi is our internal doctor ID number – eventually all referrals to ‘known’ doctors will also include this unique doctor number so the lookup will be easier
– start is the starting position in the text block to start searching from, which is incremented with each loop, to march through the text block
Obviously I’m doing other things, like using the called routine ‘parseString’, which just searches a large block of text (last parameter – the entire CCDA xml) for the first occurrence of a string (first parameter), and then use the next two parameters as start and end identifiers of strings, and then return everything between those start and end blocks. That is something I wrote because I used that logic so often.
And proc ‘CCDA_gen_msg’ which will will use msgcopy to generate a new message and return that $mh. The new message is empty, but I put several data elements in the msgmetadata USERDATA, like the provider name, msi number, etc., and then send the message downstream for further processing. If I tried to do it all in one big TCL proc I’d go crazy.
I can also post the code for get_next_followup_visit, but I know this is based on our own EMR’s DI formatting and layout. Unless you have Cerner Soarian, you will have to make up your own parsing routine.
Here is a sample section of Discharge Instructions:
Detailed Instructions from 2/27/2018 10:26 AM:
Follow-Up Appointments
Follow-Up With : Marshall, Cindy NP (844530) – NP Family Medicine
Follow Up Address Telephone 1 : 164 BROAD ST, HAMILTON 13346 (315)8244600
This is probably the worst example of XML I’ve seen. Not very hierarchical or intuitive. I have to ‘find my way’ to this section, then find ‘Follow-Up With’, then find the next text string having six numbers within parenthesis (in the example it is 844530), which is the MSI number, and then pick the provider name from that (Marshall, Cindy) and return the name, address and msi number (and the current position within the text, so the main loop can continue looking forward from the new current position).
Its daunting!
Peter Heggie
If I were faced with doing XML work via Tcl think I would approach it this way:
1. Make sure I have a valid schema for the input and the output.
2. Use the GRM functions to navigate, etc.
I think I recall even seeing a recommendation in the Cloverleaf docs to use the GRM functions when dealing with XML.
Unfortunately I do not have any experiences to share vis-a-vis XML, GRM, Tcl as I would not use Tcl inside Cloverleaf to transform XML.
email: jim.kosloskey@jim-kosloskey.com 29+ years Cloverleaf, 59 years IT - old fart.
Take a look at the tcl tdom package and xpath searching. It’s very helpful for searching XML including CCD/A’s.
# https://wiki.tcl-lang.org/1948
package require tdom
set fh [open test.ccd r]; fconfigure $fh -translation binary; set xml [read $fh]; close $fh
set doc [dom parse -simple -keepEmpties -baseurl urn:hl7-org:v3 $xml]
set root [$doc documentElement]
set ns {ns urn:hl7-org:v3}
$doc selectNodesNamespaces $ns
#
set node [$root selectNodes {ns:id}]
if {$node eq “”} {echo node is empty; return 0}
set id_root [$node getAttribute root]
set id_extension [$node getAttribute extension]
echo id_root: $id_root
echo id_extension: $id_extension
#
set node [$root selectNodes {ns:code[1]}]
if {$node eq ""} {echo node is empty; return 0}
set code_codeSystem [$node getAttribute codeSystem]
set code_displayName [$node getAttribute displayName]
echo code_codeSystem: $code_codeSystem
echo code_displayName: $code_displayName
# 17 Daws Rd.
set node [$root selectNodes {/ns:ClinicalDocument/ns:recordTarget/ns:patientRole/ns:addr[1]/ns:streetAddressLine/text()}]
if {$node eq ""} {echo node is empty; return 0}
#puts [$node data]
puts [$node nodeValue]
# data
# For a processing instruction node the data part is returned. For a text node, comment node or cdata section node the value is returned. Otherwise an error is generated.
# nodeValue ?newValue?
# Returns the value of that node object. This is the the text or the data for element nodes of type
# TEXT_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty.
# If the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the optional argument newValue is given, the node is set to that value.
#regsub -all {/} $xpath {/ns:} newxpath
#string map {/ /ns:} newxpath
-- Max Drown (Infor)
I have not used it in a long time so it may have changed but in the past I have found the Tcl DOM package to very slow plus you must supply a schema.
I have always had good luck using regular expressions to parse XML messages as long as I have a priory information about the layout. Even large files can be parsed quickly. Sometimes, if looking for a loop within a loop you may have to grab the main look and then parse it.
As an example here is a Tcl proc I used to provide with level 3 classes
The latest version of tdom is fast.
-- Max Drown (Infor)