From dd8fa766c9dda1764df025c0ced779ef3938407b Mon Sep 17 00:00:00 2001 From: Christopher Schultz Date: Thu, 4 Sep 2025 11:52:48 -0400 Subject: [PATCH] Add hl7 fingerprinting function. Signed-off-by: Christopher Schultz --- .../Fingerprint HL7 Message Fields/README.md | 13 ++ .../fingerprint.js | 149 ++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 Code Templates/Fingerprint HL7 Message Fields/README.md create mode 100644 Code Templates/Fingerprint HL7 Message Fields/fingerprint.js diff --git a/Code Templates/Fingerprint HL7 Message Fields/README.md b/Code Templates/Fingerprint HL7 Message Fields/README.md new file mode 100644 index 0000000..134dfe9 --- /dev/null +++ b/Code Templates/Fingerprint HL7 Message Fields/README.md @@ -0,0 +1,13 @@ +# Fingerprint HL7 Message Fields +Takes a simple fingerprint of an HL7 message, including some fields and optionally ignoring others. + +### Examples +Fingerprint some fields: + +```javascript +var msg = /* XML object */ +var fields = [ 'PID.2', 'PID.3', 'OBX' ]; +var ignores = [ 'MSH', 'EVN' ]; + +var fingerprint = fingerprint(msg, fields, ignores); +``` diff --git a/Code Templates/Fingerprint HL7 Message Fields/fingerprint.js b/Code Templates/Fingerprint HL7 Message Fields/fingerprint.js new file mode 100644 index 0000000..973788d --- /dev/null +++ b/Code Templates/Fingerprint HL7 Message Fields/fingerprint.js @@ -0,0 +1,149 @@ +/** + * Takes a fingerprint of a message. + * + * @param {XML} msg An XML object representing HL7. + * @param {String[]} fields An array of field names to hash (e.g. 'PID', 'SCH.5', or 'MSH.5.1') + * @param {String[]} ignores (optional) An array of fields to *completely* ignore (e.g. 'MSH', 'PID.5') + * NOTE: You can't (currently) ignore a field inside of one of the 'fields' you have already requested + * @param {String} hfunc (optional) The name of the hashing function to use. Valid values are 'hashcode' (which uses a simple Arrays.hashCode call) or any of the function supported by your JVM's MessageDigest class (e.g. MD5, SHA-1, SHA-256, etc.). The default is 'hashcode'. + * + * @return {String} A string fingerprint of the requested fields. + * + * @throws If no requested fields could be found in the message. + */ +function fingerprint(msg, fields, ignores, hfunc) { + if(!hfunc) { + hfunc = 'hashcode'; + } + + var captures = capture(msg, fields, ignores); + + if(0 < captures.length) { + // Convert to a Java array of Java strings + var len = captures.length; + var javaStrings = java.lang.reflect.Array.newInstance(new java.lang.String().getClass(), len); + for(i=0; i ''+s); // Convert all strings to js strings, just in case + + var captures = []; + + for each (seg in msg.children()) { + scan_node(seg, fields, captures, ignores); + if(0 == fields.length) { + return captures; + } + } + + return captures; +} + +/** + * Scans a node and its children for data to capture. + * + * @param {XML} msg An XML object representing HL7. + * @param {String[]} fields An array of field names whose values should be captured (e.g. 'PID', 'SCH.5', or 'MSH.5.1') + * @param {String[]} captures An array to append captured values to + * @param {String[]} ignores (optional) An array of fields to *completely* ignore (e.g. 'MSH', 'PID.5') + * NOTE: You can't (currently) ignore a field inside of one of the 'fields' you have already requested + * + * @returns Nothing + */ +function scan_node(node, fields, captures, ignores) { + var nodeName = node.localName(); // nodeName is a js string + + if(fields.includes(nodeName)) { + collect_node(node, captures); + } else if(ignores && ignores.includes(nodeName)) { + // Ignore this whole node and all its children + } else { + if(0 < node.children().length()) { + for each (child in node.children()) { + if('element' == child.nodeKind()) { // Only scan actual elements + scan_node(child, fields, captures, ignores); + + if(0 == fields.length) { + // No more fields to find; we are done + return; + } + } + } + } + } +} + +/** + * Captures all field values for the current node and its children. + * + * @param {XML} msg An XML object representing HL7. + * @param {String[]} captures An array to append captured values to + * + * @returns Nothing + */ +function collect_node(node, captures) { + if('element' == node.nodeKind() && 0 < node.children().length()) { + for each (child in node.children()) { + if('element' == node.nodeKind()) { // Only process actual elements + collect_node(child, captures); + } + } + } else { + var value = node.toString(); // value is a js string + if(0 < value.length) { + captures.push(value); + } + } +} +