| 1 | MDXMLFM1 ; HOIFO/DP/NCA - Data -> XML Utilities ; [01-10-2003 09:14] | 
|---|
| 2 | ;;1.0;CLINICAL PROCEDURES;**6**;Apr 01, 2004;Build 102 | 
|---|
| 3 | ; Integration Agreements: | 
|---|
| 4 | ; IA# 10035 [Supported] ^DPT references | 
|---|
| 5 | ; | 
|---|
| 6 | ; Special note: This routine assumes RESULTS contains the closed | 
|---|
| 7 | ;               root specification, ^TMP($J) where the output of | 
|---|
| 8 | ;               these calls will go. | 
|---|
| 9 | ;               i.e. S RESULTS=$NA(^TMP($J)) | 
|---|
| 10 | ; | 
|---|
| 11 | ;               Calling app needs to call NEWDOC^MDXMLFM *ONCE* | 
|---|
| 12 | ;               to clear the global before building an XML document. | 
|---|
| 13 | ; | 
|---|
| 14 | LOADALL(IENLIST,DD,FLDS) ; Load complete dataset | 
|---|
| 15 | ; | 
|---|
| 16 | ; Loads entire dataset from @IENLIST@(...) | 
|---|
| 17 | ; | 
|---|
| 18 | N MDIEN S MDIEN=0 | 
|---|
| 19 | D NEWDOC("RESULTS") | 
|---|
| 20 | D XMLDATA("STATUS","OK") | 
|---|
| 21 | F  S MDIEN=$O(@IENLIST@(MDIEN)) Q:'MDIEN  S MDFDAT=$G(@IENLIST@(MDIEN)) D | 
|---|
| 22 | .D BLDXML(DD,MDIEN,.FLDS,MDFDAT) | 
|---|
| 23 | D ENDDOC("RESULTS") | 
|---|
| 24 | Q | 
|---|
| 25 | ; | 
|---|
| 26 | LOADONE(IEN,DD,FLDS) ; Load single record as dataset | 
|---|
| 27 | ; | 
|---|
| 28 | ; Not to be used recursively | 
|---|
| 29 | ; Assumes complete data set is one record | 
|---|
| 30 | ; | 
|---|
| 31 | D NEWDOC("RESULTS") | 
|---|
| 32 | D XMLDATA("STATUS","OK") | 
|---|
| 33 | D BLDXML(DD,IEN,.FLDS) | 
|---|
| 34 | D ENDDOC("RESULTS") | 
|---|
| 35 | Q | 
|---|
| 36 | ; | 
|---|
| 37 | LOADFILE(MDNUM,MDROOT,MDFLDS) ; Bulk load file MDNUM into XML | 
|---|
| 38 | ; | 
|---|
| 39 | ; Loads all records and all fields in the DD# MDNUM | 
|---|
| 40 | ; Optionally include a closed root of the index to use MDROOT | 
|---|
| 41 | ; Optionally include a list of fields #;#;#;# will default to "*" | 
|---|
| 42 | ; | 
|---|
| 43 | N MDIEN,MDNODE,MDIDS,MDTEMP,MDHDR,MDNAME | 
|---|
| 44 | S MDTEMP=$NA(^TMP("MD_TEMP",$J)) K @MDTEMP | 
|---|
| 45 | S MDNAME=$$GET1^DID(MDNUM,,,"NAME") | 
|---|
| 46 | I $G(MDROOT)]"" S:'$D(@MDROOT)#2 MDROOT="" | 
|---|
| 47 | S:$G(MDROOT)="" MDROOT=$$ROOT^DILFD(MDNUM,,1) | 
|---|
| 48 | S:$G(MDFLDS)="" MDFLDS="*" | 
|---|
| 49 | ; | 
|---|
| 50 | ; Load the records via Fileman GETS^DIQ | 
|---|
| 51 | ; | 
|---|
| 52 | S MDIEN=0 | 
|---|
| 53 | F  S MDIEN=$O(@MDROOT@(MDIEN)) Q:'MDIEN  D | 
|---|
| 54 | .D GETS^DIQ(MDNUM,MDIEN_",",MDFLDS,"I",MDTEMP) | 
|---|
| 55 | ; | 
|---|
| 56 | ; Grab the tags and types if any records were processed | 
|---|
| 57 | ; | 
|---|
| 58 | S MDIEN=$O(@MDTEMP@(MDNUM,"")) D:MDIEN]"" | 
|---|
| 59 | .F X=0:0 S X=$O(@MDTEMP@(MDNUM,MDIEN,X)) Q:'X  D | 
|---|
| 60 | ..S MDTAG=$$GET1^DID(MDNUM,X,,"LABEL") | 
|---|
| 61 | ..S MDTYPE=$$GET1^DID(MDNUM,X,,"TYPE") | 
|---|
| 62 | ..S MDPTR=$$GET1^DID(MDNUM,X,,"POINTER") | 
|---|
| 63 | ..S @MDTEMP@(MDNUM,0,X,"TAG")=$$TAGSAFE(MDTAG) | 
|---|
| 64 | ..S @MDTEMP@(MDNUM,0,X,"TYPE")=MDTYPE | 
|---|
| 65 | ..S @MDTEMP@(MDNUM,0,X,"PTR")=MDPTR | 
|---|
| 66 | ; | 
|---|
| 67 | ; Ok, lets add the file | 
|---|
| 68 | ; | 
|---|
| 69 | D XMLDATA("TABLENAME",MDNAME) | 
|---|
| 70 | S MDIENS=$O(@MDTEMP@(MDNUM,0)) | 
|---|
| 71 | F  Q:MDIENS=""  D | 
|---|
| 72 | .D XMLHDR("RECORD") | 
|---|
| 73 | .S MDFLD=$O(@MDTEMP@(MDNUM,MDIENS,0)) | 
|---|
| 74 | .F  Q:MDFLD=""  D | 
|---|
| 75 | ..S MDTAG=@MDTEMP@(MDNUM,0,MDFLD,"TAG") | 
|---|
| 76 | ..S MDATA=@MDTEMP@(MDNUM,MDIENS,MDFLD,"I") | 
|---|
| 77 | ..S MDTYPE=@MDTEMP@(MDNUM,0,MDFLD,"TYPE") D | 
|---|
| 78 | ...I MDTYPE["WORD" D XMLWP(MDTAG,MDATA) Q | 
|---|
| 79 | ...I MDTYPE["DATE" D XMLDT(MDTAG,MDATA) Q | 
|---|
| 80 | ...D XMLDATA(MDTAG,MDATA) | 
|---|
| 81 | ..S MDFLD=$O(@MDTEMP@(MDNUM,MDIENS,MDFLD)) | 
|---|
| 82 | .D XMLFTR("RECORD") | 
|---|
| 83 | .S MDIENS=$O(@MDTEMP@(MDNUM,MDIENS)) | 
|---|
| 84 | Q | 
|---|
| 85 | ; | 
|---|
| 86 | BLDFLD(RESULTS,DD,FLDS) ; Add a field or field^field to the FLDS array | 
|---|
| 87 | F  D  Q:FLDS']"" | 
|---|
| 88 | .S Y=$P(FLDS,"^",1),FLDS=$P(FLDS,"^",2,250) | 
|---|
| 89 | .S MDFLD=$P(Y,";",1) K RESULTS(MDFLD) | 
|---|
| 90 | .I $P(Y,";",2)]"" S RESULTS(MDFLD,"FORMAT")=$P(Y,";",2) | 
|---|
| 91 | .E  S RESULTS(MDFLD,"FORMAT")="I" | 
|---|
| 92 | .I $P(Y,";",3)]"" S RESULTS(MDFLD,"TAG")=$P(Y,";",3) | 
|---|
| 93 | .E  S RESULTS(MDFLD,"TAG")=$TR($$GET1^DID(DD,MDFLD,"","LABEL")," ","_") | 
|---|
| 94 | .I $P(Y,";",4)]"" S RESULTS(MDFLD,"TYPE")=$P(Y,";",4) | 
|---|
| 95 | .E  S RESULTS(MDFLD,"TYPE")=$$GET1^DID(DD,+MDFLD,"","TYPE") | 
|---|
| 96 | Q | 
|---|
| 97 | ; | 
|---|
| 98 | BLDXML(DD,IEN,FLDS,MDFDAT) ; Builds an XML Record based on DD, IEN, and FLDS | 
|---|
| 99 | ; Note: this is a standalone module requiring DD and IEN | 
|---|
| 100 | ; so that it can be easily used by the custom query routines | 
|---|
| 101 | N MDFLD,MDIENS,MDKTR,X,Y | 
|---|
| 102 | D XMLHDR("RECORD") | 
|---|
| 103 | S MDIENS=IEN_",",MDFLD="",MDKTR=0 | 
|---|
| 104 | F  S MDFLD=$O(FLDS(MDFLD)) Q:MDFLD=""  D | 
|---|
| 105 | .; .001 is always the IEN *IF* it is included in the view | 
|---|
| 106 | .I +MDFLD=.001 D XMLDATA(FLDS(MDFLD,"TAG"),+MDIENS) S MDKTR=MDKTR+1 Q | 
|---|
| 107 | .S MDFMT=$G(FLDS(MDFLD,"FORMAT"),"I") | 
|---|
| 108 | .; Process as a date | 
|---|
| 109 | .I $G(FLDS(MDFLD,"TYPE"))["DATE" D  Q | 
|---|
| 110 | ..S X=$$GET1^DIQ(DD,MDIENS,MDFLD,"I") | 
|---|
| 111 | ..I X]""&(MDFMT'="I") D  S X=Y | 
|---|
| 112 | ...S Y=($E(X,1,3)+1700)_"-"_$E(X,4,5)_"-"_$E(X,6,7) Q:X'["." | 
|---|
| 113 | ...S X=X+.0000001  ; Add it in ensure all the time parts | 
|---|
| 114 | ...S Y=Y_" "_$E(X,9,10)_":"_$E(X,11,12)_":"_$E(X,13,14) | 
|---|
| 115 | ..D XMLDATA(FLDS(MDFLD,"TAG"),X) | 
|---|
| 116 | .; Process as WP | 
|---|
| 117 | .I $G(FLDS(MDFLD,"TYPE"))["WORD" D  Q | 
|---|
| 118 | ..D XMLHDR(FLDS(MDFLD,"TAG")) | 
|---|
| 119 | ..S Y=$O(@RESULTS@(""),-1)+1 | 
|---|
| 120 | ..S X=$$GET1^DIQ(DD,MDIENS,MDFLD,"",$NA(@RESULTS@(Y))) | 
|---|
| 121 | ..D XMLFTR(FLDS(MDFLD,"TAG")) | 
|---|
| 122 | .; Just return with specified data format | 
|---|
| 123 | .S MDKTR=MDKTR+1 | 
|---|
| 124 | .D XMLDATA(FLDS(MDFLD,"TAG"),$P(MDFDAT,U,MDKTR)) | 
|---|
| 125 | D XMLFTR("RECORD") | 
|---|
| 126 | Q | 
|---|
| 127 | ; | 
|---|
| 128 | XMLCMT(COMMENT) ; Add a comment to a document | 
|---|
| 129 | D XMLADD("<!-- "_COMMENT_" -->") | 
|---|
| 130 | Q | 
|---|
| 131 | ; | 
|---|
| 132 | XMLHDR(TAG) ; Add a header tag to the global | 
|---|
| 133 | S TAG=$$TAGSAFE(TAG) | 
|---|
| 134 | D XMLADD("<"_TAG_">") | 
|---|
| 135 | Q | 
|---|
| 136 | ; | 
|---|
| 137 | XMLFTR(TAG) ; Add a footer tag to the global | 
|---|
| 138 | D XMLHDR("/"_TAG) | 
|---|
| 139 | Q | 
|---|
| 140 | ; | 
|---|
| 141 | XMLDATA(TAG,X) ; Add a data element to the global | 
|---|
| 142 | S TAG=$$TAGSAFE(TAG) | 
|---|
| 143 | I $G(X)="" D XMLADD("<"_TAG_" />") | 
|---|
| 144 | E  D XMLADD("<"_TAG_">"_$$XMLSAFE(X)_"</"_TAG_">") | 
|---|
| 145 | Q | 
|---|
| 146 | ; | 
|---|
| 147 | XMLPT(X) ; Add a standard pt identifier node | 
|---|
| 148 | S X(1,"NAME")=$P(^DPT(X,0),U) | 
|---|
| 149 | S X(2,"SSN")=$P(^DPT(X,0),U,9) | 
|---|
| 150 | S X(3,"SEX")=$P(^DPT(X,0),U,2) | 
|---|
| 151 | S Y=$P(^DPT(X,0),U,3) | 
|---|
| 152 | S Y(1)=1700+$E(Y,1,3),Y(2)=+$E(Y,4,5),Y(3)=+$E(Y,6,7) | 
|---|
| 153 | S X(4,"DOB_Y")=Y(1) | 
|---|
| 154 | S X(5,"DOB_M")=Y(2) | 
|---|
| 155 | S X(6,"DOB_D")=Y(3) | 
|---|
| 156 | D XMLIDS("PATIENT",.X,1) | 
|---|
| 157 | Q | 
|---|
| 158 | ; | 
|---|
| 159 | XMLWP(TAG,X) ; Add text in array @X to the global | 
|---|
| 160 | S TAG=$$TAGSAFE(TAG) | 
|---|
| 161 | I $G(X)="" D XMLADD("<"_TAG_" />") Q  ; Empty global ref | 
|---|
| 162 | D XMLHDR(TAG) | 
|---|
| 163 | F Y=0:0 S Y=$O(@X@(Y)) Q:'Y  D XMLADD(@X@(Y)) | 
|---|
| 164 | D XMLFTR(TAG) | 
|---|
| 165 | Q | 
|---|
| 166 | ; | 
|---|
| 167 | XMLDT(TAG,X) ; Add date or date/time to the global | 
|---|
| 168 | S TAG=$$TAGSAFE(TAG) | 
|---|
| 169 | I $G(X)="" D XMLADD("<"_TAG_" />") Q  ; No data | 
|---|
| 170 | ; Build the ID array | 
|---|
| 171 | S X(1,"Y")=(1700+$E(X,1,3)) | 
|---|
| 172 | S X(2,"M")=+$E(X,4,5) | 
|---|
| 173 | S X(3,"D")=+$E(X,6,7) | 
|---|
| 174 | D:X]"." | 
|---|
| 175 | .S X=X+.0000001 | 
|---|
| 176 | .S X(4,"hh")=+$E(X,9,10) | 
|---|
| 177 | .S X(5,"mm")=+$E(X,11,12) | 
|---|
| 178 | .S X(6,"ss")=+$E(X,13,14) | 
|---|
| 179 | D XMLIDS(TAG,.X,1) | 
|---|
| 180 | Q | 
|---|
| 181 | ; | 
|---|
| 182 | XMLIDS(TAG,IDS,CLOSE) ; Add a data element to the global with ids | 
|---|
| 183 | S TAG="<"_$$TAGSAFE(TAG) | 
|---|
| 184 | F X=0:0 S X=$O(IDS(X)) Q:'X  D | 
|---|
| 185 | .S Y="" F  S Y=$O(IDS(X,Y)) Q:Y=""  D | 
|---|
| 186 | ..S TAG=TAG_" "_Y_"="""_$$XMLSAFE(IDS(X,Y))_"""" | 
|---|
| 187 | S:$G(CLOSE) TAG=TAG_" /" ; Close out the tag element | 
|---|
| 188 | S TAG=TAG_">" | 
|---|
| 189 | D XMLADD(TAG) | 
|---|
| 190 | Q | 
|---|
| 191 | ; | 
|---|
| 192 | XMLADD(X) ; Add to the global | 
|---|
| 193 | S @RESULTS@($O(@RESULTS@(""),-1)+1)=$G(X) | 
|---|
| 194 | Q | 
|---|
| 195 | ; | 
|---|
| 196 | ADDERR(X) ; | 
|---|
| 197 | S MDERROR($O(MDERR(""),-1)+1)=X | 
|---|
| 198 | Q | 
|---|
| 199 | ; | 
|---|
| 200 | XMLOK(RESULTS) ; Build an XML OK message | 
|---|
| 201 | K @RESULTS | 
|---|
| 202 | S @RESULTS@(0)="<RESULTS>" | 
|---|
| 203 | S @RESULTS@(1)="<STATUS>OK</STATUS>" | 
|---|
| 204 | S @RESULTS@(2)="</RESULTS>" | 
|---|
| 205 | Q | 
|---|
| 206 | ; | 
|---|
| 207 | XMLERR(ERRMSG) ; Build an XML error Message to return | 
|---|
| 208 | K @RESULTS | 
|---|
| 209 | S @RESULTS@(0)="<RESULTS>" | 
|---|
| 210 | S @RESULTS@(1)="<STATUS>ERROR</STATUS>" | 
|---|
| 211 | I $D(ERRMSG)=1 D  ; Simple one liner | 
|---|
| 212 | .S @RESULTS@(2)="<MESSAGE>"_$$XMLSAFE(ERRMSG)_"</MESSAGE>" | 
|---|
| 213 | I $D(ERRMSG)>2 D  ; Load the array into the XML message | 
|---|
| 214 | .S @RESULTS@(2)="<MESSAGE>"_$G(ERRMSG,"NO DESCRIPTION") | 
|---|
| 215 | .S X="ERRMSG" F  S X=$Q(@X) Q:X=""!(X'?1"ERRMSG(".E)  D | 
|---|
| 216 | ..S @RESULTS@($O(@RESULTS@(""),-1)+1)=$$XMLSAFE(@X) | 
|---|
| 217 | .S @RESULTS@($O(@RESULTS@(""),-1)+1)="</MESSAGE>" | 
|---|
| 218 | S @RESULTS@($O(@RESULTS@(""),-1)+1)="</RESULTS>" | 
|---|
| 219 | Q | 
|---|
| 220 | ; | 
|---|
| 221 | XMLDATE(X) ; Transform Y into XML safe date | 
|---|
| 222 | N Y | 
|---|
| 223 | S Y=($E(X,1,3)+1700)_"-"_$E(X,4,5)_"-"_$E(X,6,7) | 
|---|
| 224 | D:X["." | 
|---|
| 225 | .S X=X+.0000001 | 
|---|
| 226 | .S Y=Y_" "_$E(X,9,10)_":"_$E(X,11,12)_":"_$E(X,13,14) | 
|---|
| 227 | Q Y | 
|---|
| 228 | ; | 
|---|
| 229 | XMLSAFE(X) ; Transform X into XML safe data | 
|---|
| 230 | S X=$$TRNSLT(X,"&","&") | 
|---|
| 231 | S X=$$TRNSLT(X,"<","<") | 
|---|
| 232 | S X=$$TRNSLT(X,">",">") | 
|---|
| 233 | S X=$$TRNSLT(X,"'","'") | 
|---|
| 234 | S X=$$TRNSLT(X,"""",""") | 
|---|
| 235 | Q X | 
|---|
| 236 | ; | 
|---|
| 237 | TAGSAFE(X) ; Transform X into XML tag | 
|---|
| 238 | S:X?1N.E X="_"_X  ; Remove starting numeric | 
|---|
| 239 | Q $TR(X," '`()<>*[]","__________") | 
|---|
| 240 | ; | 
|---|
| 241 | NEWDOC(ROOT,COMMENT) ; Start a new document | 
|---|
| 242 | K @RESULTS | 
|---|
| 243 | D XMLADD("<?xml version=""1.0"" standalone=""yes""?>") | 
|---|
| 244 | I $G(COMMENT)]"" D XMLCMT(COMMENT) | 
|---|
| 245 | D XMLHDR($G(ROOT,"RESULTS")) | 
|---|
| 246 | Q | 
|---|
| 247 | ; | 
|---|
| 248 | ENDDOC(ROOT) ; End this document | 
|---|
| 249 | D XMLFTR($G(ROOT,"RESULTS")) | 
|---|
| 250 | Q | 
|---|
| 251 | ; | 
|---|
| 252 | TRNSLT(X,X1,X2) ; Translate every Y to Z in X | 
|---|
| 253 | N Y | 
|---|
| 254 | Q:X'[X1 X  ; Nothing to translate | 
|---|
| 255 | S Y="" F  Q:X=""  D | 
|---|
| 256 | .I X[X1 S Y=Y_$P(X,X1)_X2,X=$P(X,X1,2,250) Q | 
|---|
| 257 | .S Y=Y_X,X="" | 
|---|
| 258 | Q Y | 
|---|
| 259 | ; | 
|---|