diff --git a/p/GPLCCR.m b/p/GPLCCR.m index af2cd2c..5ade73c 100644 --- a/p/GPLCCR.m +++ b/p/GPLCCR.m @@ -1,146 +1,148 @@ -GPLCCR ; CCDCCR/GPL - CCR MAIN PROCESSING; 6/6/08 - ;;0.1;CCDCCR;nopatch;noreleasedate - ; - ; EXPORT A CCR - ; -EXPORT ; EXPORT ENTRY POINT FOR CCR - ; Select a patient. - S DIC=2,DIC(0)="AEMQ" D ^DIC - I Y<1 Q ; EXIT - S DFN=$P(Y,U,1) ; SET THE PATIENT - N CCRGLO - D CCRRPC(.CCRGLO,DFN,"CCR","","","") - S OARY=$NA(^TMP($J,DFN,"CCR",1)) - S ONAM="PAT_"_DFN_"_CCR_V1.xml" - S ODIR="/home/glilly/CCROUT" - D OUTPUT^GPLXPATH(OARY,ONAM,ODIR) - Q - ; -CCRRPC(CCRGRTN,DFN,CCRPART,TIME1,TIME2,HDRARY) ; RPC ENTRY POINT FOR CCR OUTPUT - ; CCRGRTN IS RETURN ARRAY PASSED BY NAME - ; DFN IS PATIENT IEN - ; CCRPART IS "CCR" FOR ENTIRE CCR, OR SECTION NAME FOR A PART OF THE - ; CCR BODY.. PARTS INCLUDE "PROBLEMS" "VITALS" ETC - ; TIME1 IS STARTING TIME TO INCLUDE - NULL MEANS ALL - ; TIME2 IS ENDING TIME TO INCLUDE TIME IS FILEMAN TIME - NULL MEANS NOW - ; HDRARY IS THE HEADER ARRAY DEFINING THE "FROM" AND "TO" VARIABLES - ; IF NULL WILL DEFAULT TO "FROM" DUZ AND "TO" DFN - S DEBUG=1 - S TGLOBAL=$NA(^TMP($J,"TEMPLATE")) ; GLOBAL FOR STORING TEMPLATE - S CCRGLO=$NA(^TMP($J,DFN,"CCR")) ; GLOBAL FOR BUILDING THE CCR - S ACTGLO=$NA(^TMP($J,DFN,"ACTORS")); GLOBAL FOR ALL ACTORS IN CCR - ; TO GET PART OF THE CCR RETURNED, PASS CCRPART="PROBLEMS" ETC - S CCRGRTN=$NA(^TMP($J,DFN,CCRPART)) ; RTN GLO NM OF PART OR ALL OF CCR - D LOAD^GPLCCR0(TGLOBAL) ; LOAD THE CCR TEMPLATE - D CP^GPLXPATH(TGLOBAL,CCRGLO) ; COPY THE TEMPLATE TO THE CCR GLOBAL - ; - ; DELETE THE BODY, ACTORS AND SIGNATURES SECTIONS FROM THE CCR GLOBAL - ; THESE WILL BE POPULATED AFTER CALLS TO THE XPATH PROCESSING ROUTINES - D REPLACE^GPLXPATH(CCRGLO,"","//ContinuityOfCareRecord/Body") - D REPLACE^GPLXPATH(CCRGLO,"","//ContinuityOfCareRecord/Actors") - D REPLACE^GPLXPATH(CCRGLO,"","//ContinuityOfCareRecord/Signatures") - I DEBUG F I=1:1:@CCRGLO@(0) W @CCRGLO@(I),! - ; - D HDRMAP(CCRGLO,DFN,HDRARY) ; MAP HEADER VARIABLES - ; - S CCRXTAB="^TMP($J,""CCRSTEP"")" ; GLOBAL TO STORE CCR PROCESSING STEPS - D INITSTPS(CCRXTAB) ; INITIALIZED CCR PROCESSING STEPS - N I,XI,TAG,RTN,CALL,XPATH,IXML,OXML,INXML,CCRBLD - F I=1:1:@CCRXTAB@(0) D ; PROCESS THE CCR BODY SECTIONS - . S XI=@CCRXTAB@(I) ; CALL COPONENTS TO PARSE - . S RTN=$P(XI,";",2) ; NAME OF ROUTINE TO CALL - . S TAG=$P(XI,";",1) ; LABEL INSIDE ROUTINE TO CALL - . S XPATH=$P(XI,";",3) ; XPATH TO XML TO PASS TO ROUTINE - . D QUERY^GPLXPATH(TGLOBAL,XPATH,"INXML") ; EXTRACT XML TO PASS - . S IXML="INXML" - . S OXML=$P(XI,";",4) ; ARRAY FOR SECTION VALUES - . ; W OXML,! - . S CALL="D "_TAG_"^"_RTN_"(IXML,DFN,OXML)" ; SETUP THE CALL - . W "RUNNING ",CALL,! - . X CALL - . ; NOW INSERT THE RESULTS IN THE CCR BUFFER - . D INSERT^GPLXPATH(CCRGLO,OXML,"//ContinuityOfCareRecord/Body") - . I DEBUG F GPLI=1:1:@OXML@(0) W @OXML@(GPLI),! - D ACTLST^GPLCCR(CCRGLO,ACTGLO) ; GEN THE ACTOR LIST - Q - ; -INITSTPS(TAB) ; INITIALIZE CCR PROCESSING STEPS - ; TAB IS PASSED BY NAME - ; W "TAB= ",TAB,! - ; D PUSH^GPLXPATH(TAB,"EXTRACT;GPLVITALS;//ContinuityOfCareRecord/Body/VitalSigns;^TMP($J,DFN,""VITALS"")") - D PUSH^GPLXPATH(TAB,"EXTRACT;GPLPROBS;//ContinuityOfCareRecord/Body/Problems;^TMP($J,DFN,""PROBLEMS"")") - Q - ; -HDRMAP(CXML,DFN,IHDR) ; MAP HEADER VARIABLES: FROM, TO ECT - N VMAP S VMAP=$NA(^TMP($J,DFN,"HEADER")) - ; K @VMAP - I IHDR="" D ; HEADER ARRAY IS NOT PROVIDED, USE DEFAULTS - . S @VMAP@("ACTORPATIENT")="ACTORPATIENT_"_DFN - . S @VMAP@("ACTORFROM")="ACTORPROVIDER_"_DUZ ; FROM DUZ - ??? - . S @VMAP@("ACTORFROM2")="ACTORPROVIDER_"_DUZ ; NEED A BETTER WAY - . S @VMAP@("ACTORTO")="ACTORPATIENT_"_DFN ; FOR TEST PURPOSES, - . ; THIS IS THE USE CASE FOR THE PHR WHERE "TO" IS THE PATIENT - I IHDR'="" D ; HEADER VALUES ARE PROVIDED - . D CP^GPLXPATH(IHDR,VMAP) ; COPY HEADER VARIABLES TO MAP ARRAY - N CTMP - D MAP^GPLXPATH(CXML,VMAP,"CTMP") - D CP^GPLXPATH("CTMP",CXML) - Q - ; -ACTLST(AXML,ACTRTN) ; RETURN THE ACTOR LIST FOR THE XML IN AXML - ; AXML AND ACTRTN ARE PASSED BY NAME - ; EACH ACTOR RECORD HAS 3 PARTS - IE IF OBJECTID=ACTORPATIENT_2 - ; P1= OBJECTID - ACTORPATIENT_2 - ; P2= OBJECT TYPE - PATIENT OR PROVIDER OR SOFTWARE OR INSTITUTION - ; OR PERSON(IN PATIENT FILE IE NOK) - ; P3= IEN RECORD NUMBER FOR ACTOR - 2 - N I,J,K,L - K @ACTRTN ; CLEAR RETURN ARRAY - F I=1:1:@AXML@(0) D ; SCAN ALL LINES - . I @AXML@(I)?.E1"".E D ; THERE IS AN ACTOR ON THIS LINE - . . S J=$P($P(@AXML@(I),"",2),"",1) - . . W "=>",J,! - . . S K(J)="" ; HASHING ACTOR TO GET RID OF DUPLICATES - S I="" ; GOING TO $O THROUGH THE HASH - F J=0:0 D Q:$O(K(I))="" - . S I=$O(K(I)) ; WALK THROUGH THE HASH OF ACTORS - . S $P(L,U,1)=I ; FIRST PIECE IS THE OBJECT ID - . S $P(L,U,2)=$P($P(I,"ACTOR",2),"_",1) ; ACTOR TYPE: PATIENT/PROVIDER - . S $P(L,U,3)=$P(I,"_",2) ; IEN RECORD NUMBER FOR ACTOR - . D PUSH^GPLXPATH(ACTRTN,L) ; ADD THE ACTOR TO THE RETURN ARRAY - Q - ; -TEST ; RUN ALL THE TEST CASES - ;D TESTALL^GPLUNIT("GPLCCR") - D ZTEST^GPLCCR("PROBLEMS") - W "TESTING RETURNED FROM PROBLMES",! - D ZTEST^GPLCCR("CCR") - Q - ; -ZTEST(WHICH) ; RUN ONE SET OF TESTS - N ZTMP - D ZLOAD^GPLUNIT("ZTMP","GPLCCR") - D ZTEST^GPLUNIT(.ZTMP,WHICH) - Q - ; -TLIST ; LIST THE TESTS - N ZTMP - D ZLOAD^GPLUNIT("ZTMP","GPLCCR") - D TLIST^GPLUNIT(.ZTMP) - Q - ; -;;> -;;> -;;>>>K GPL S GPL="" -;;>>>D CCRRPC^GPLCCR(.GPL,"2","PROBLEMS","","","") -;;>>?@GPL@(@GPL@(0))="" -;;> -;;>>>D ^%ZTER -;;>>>K GPL S GPL="" -;;>>>D CCRRPC^GPLCCR(.GPL,"2","CCR","","","") -;;>>?@GPL@(@GPL@(0))="" -;;> -;;>>>N TCCR -;;>>>D CCRRPC^GPLCCR(.TCCR,"2","CCR","","","") -;;>>>D ACTLST^GPLCCR("TCCR","ACTTEST") -;;> +GPLCCR ; CCDCCR/GPL - CCR MAIN PROCESSING; 6/6/08 + ;;0.1;CCDCCR;nopatch;noreleasedate + ; + ; EXPORT A CCR + ; +EXPORT ; EXPORT ENTRY POINT FOR CCR + ; Select a patient. + S DIC=2,DIC(0)="AEMQ" D ^DIC + I Y<1 Q ; EXIT + S DFN=$P(Y,U,1) ; SET THE PATIENT + N CCRGLO + D CCRRPC(.CCRGLO,DFN,"CCR","","","") + S OARY=$NA(^TMP($J,DFN,"CCR",1)) + S ONAM="PAT_"_DFN_"_CCR_V1.xml" + S ODIR="/home/glilly/CCROUT" + ;S ODIR="/home/cedwards/" + D OUTPUT^GPLXPATH(OARY,ONAM,ODIR) + Q + ; +CCRRPC(CCRGRTN,DFN,CCRPART,TIME1,TIME2,HDRARY) ; RPC ENTRY POINT FOR CCR OUTPUT + ; CCRGRTN IS RETURN ARRAY PASSED BY NAME + ; DFN IS PATIENT IEN + ; CCRPART IS "CCR" FOR ENTIRE CCR, OR SECTION NAME FOR A PART OF THE + ; CCR BODY.. PARTS INCLUDE "PROBLEMS" "VITALS" ETC + ; TIME1 IS STARTING TIME TO INCLUDE - NULL MEANS ALL + ; TIME2 IS ENDING TIME TO INCLUDE TIME IS FILEMAN TIME - NULL MEANS NOW + ; HDRARY IS THE HEADER ARRAY DEFINING THE "FROM" AND "TO" VARIABLES + ; IF NULL WILL DEFAULT TO "FROM" DUZ AND "TO" DFN + S DEBUG=0 + S TGLOBAL=$NA(^TMP($J,"TEMPLATE")) ; GLOBAL FOR STORING TEMPLATE + S CCRGLO=$NA(^TMP($J,DFN,"CCR")) ; GLOBAL FOR BUILDING THE CCR + S ACTGLO=$NA(^TMP($J,DFN,"ACTORS")); GLOBAL FOR ALL ACTORS IN CCR + ; TO GET PART OF THE CCR RETURNED, PASS CCRPART="PROBLEMS" ETC + S CCRGRTN=$NA(^TMP($J,DFN,CCRPART)) ; RTN GLO NM OF PART OR ALL OF CCR + D LOAD^GPLCCR0(TGLOBAL) ; LOAD THE CCR TEMPLATE + D CP^GPLXPATH(TGLOBAL,CCRGLO) ; COPY THE TEMPLATE TO THE CCR GLOBAL + ; + ; DELETE THE BODY, ACTORS AND SIGNATURES SECTIONS FROM THE CCR GLOBAL + ; THESE WILL BE POPULATED AFTER CALLS TO THE XPATH PROCESSING ROUTINES + D REPLACE^GPLXPATH(CCRGLO,"","//ContinuityOfCareRecord/Body") + D REPLACE^GPLXPATH(CCRGLO,"","//ContinuityOfCareRecord/Actors") + D REPLACE^GPLXPATH(CCRGLO,"","//ContinuityOfCareRecord/Signatures") + I DEBUG F I=1:1:@CCRGLO@(0) W @CCRGLO@(I),! + ; + D HDRMAP(CCRGLO,DFN,HDRARY) ; MAP HEADER VARIABLES + ; + K ^TMP($J,"CCRSTEP") ; KILL GLOBAL PRIOR TO ADDING TO IT + S CCRXTAB="^TMP($J,""CCRSTEP"")" ; GLOBAL TO STORE CCR PROCESSING STEPS + D INITSTPS(CCRXTAB) ; INITIALIZED CCR PROCESSING STEPS + N I,XI,TAG,RTN,CALL,XPATH,IXML,OXML,INXML,CCRBLD + F I=1:1:@CCRXTAB@(0) D ; PROCESS THE CCR BODY SECTIONS + . S XI=@CCRXTAB@(I) ; CALL COPONENTS TO PARSE + . S RTN=$P(XI,";",2) ; NAME OF ROUTINE TO CALL + . S TAG=$P(XI,";",1) ; LABEL INSIDE ROUTINE TO CALL + . S XPATH=$P(XI,";",3) ; XPATH TO XML TO PASS TO ROUTINE + . D QUERY^GPLXPATH(TGLOBAL,XPATH,"INXML") ; EXTRACT XML TO PASS + . S IXML="INXML" + . S OXML=$P(XI,";",4) ; ARRAY FOR SECTION VALUES + . ; W OXML,! + . S CALL="D "_TAG_"^"_RTN_"(IXML,DFN,OXML)" ; SETUP THE CALL + . W "RUNNING ",CALL,! + . X CALL + . ; NOW INSERT THE RESULTS IN THE CCR BUFFER + . D INSERT^GPLXPATH(CCRGLO,OXML,"//ContinuityOfCareRecord/Body") + . I DEBUG F GPLI=1:1:@OXML@(0) W @OXML@(GPLI),! + D ACTLST^GPLCCR(CCRGLO,ACTGLO) ; GEN THE ACTOR LIST + Q + ; +INITSTPS(TAB) ; INITIALIZE CCR PROCESSING STEPS + ; TAB IS PASSED BY NAME + ; W "TAB= ",TAB,! + D PUSH^GPLXPATH(TAB,"EXTRACT;GPLVITALS;//ContinuityOfCareRecord/Body/VitalSigns;^TMP($J,DFN,""VITALS"")") + D PUSH^GPLXPATH(TAB,"EXTRACT;GPLPROBS;//ContinuityOfCareRecord/Body/Problems;^TMP($J,DFN,""PROBLEMS"")") + Q + ; +HDRMAP(CXML,DFN,IHDR) ; MAP HEADER VARIABLES: FROM, TO ECT + N VMAP S VMAP=$NA(^TMP($J,DFN,"HEADER")) + ; K @VMAP + I IHDR="" D ; HEADER ARRAY IS NOT PROVIDED, USE DEFAULTS + . S @VMAP@("ACTORPATIENT")="ACTORPATIENT_"_DFN + . S @VMAP@("ACTORFROM")="ACTORPROVIDER_"_DUZ ; FROM DUZ - ??? + . S @VMAP@("ACTORFROM2")="ACTORPROVIDER_"_DUZ ; NEED A BETTER WAY + . S @VMAP@("ACTORTO")="ACTORPATIENT_"_DFN ; FOR TEST PURPOSES, + . ; THIS IS THE USE CASE FOR THE PHR WHERE "TO" IS THE PATIENT + I IHDR'="" D ; HEADER VALUES ARE PROVIDED + . D CP^GPLXPATH(IHDR,VMAP) ; COPY HEADER VARIABLES TO MAP ARRAY + N CTMP + D MAP^GPLXPATH(CXML,VMAP,"CTMP") + D CP^GPLXPATH("CTMP",CXML) + Q + ; +ACTLST(AXML,ACTRTN) ; RETURN THE ACTOR LIST FOR THE XML IN AXML + ; AXML AND ACTRTN ARE PASSED BY NAME + ; EACH ACTOR RECORD HAS 3 PARTS - IE IF OBJECTID=ACTORPATIENT_2 + ; P1= OBJECTID - ACTORPATIENT_2 + ; P2= OBJECT TYPE - PATIENT OR PROVIDER OR SOFTWARE OR INSTITUTION + ; OR PERSON(IN PATIENT FILE IE NOK) + ; P3= IEN RECORD NUMBER FOR ACTOR - 2 + N I,J,K,L + K @ACTRTN ; CLEAR RETURN ARRAY + F I=1:1:@AXML@(0) D ; SCAN ALL LINES + . I @AXML@(I)?.E1"".E D ; THERE IS AN ACTOR ON THIS LINE + . . S J=$P($P(@AXML@(I),"",2),"",1) + . . ;W "=>",J,! + . . S K(J)="" ; HASHING ACTOR TO GET RID OF DUPLICATES + S I="" ; GOING TO $O THROUGH THE HASH + F J=0:0 D Q:$O(K(I))="" + . S I=$O(K(I)) ; WALK THROUGH THE HASH OF ACTORS + . S $P(L,U,1)=I ; FIRST PIECE IS THE OBJECT ID + . S $P(L,U,2)=$P($P(I,"ACTOR",2),"_",1) ; ACTOR TYPE: PATIENT/PROVIDER + . S $P(L,U,3)=$P(I,"_",2) ; IEN RECORD NUMBER FOR ACTOR + . D PUSH^GPLXPATH(ACTRTN,L) ; ADD THE ACTOR TO THE RETURN ARRAY + Q + ; +TEST ; RUN ALL THE TEST CASES + ;D TESTALL^GPLUNIT("GPLCCR") + D ZTEST^GPLCCR("PROBLEMS") + W "TESTING RETURNED FROM PROBLMES",! + D ZTEST^GPLCCR("CCR") + Q + ; +ZTEST(WHICH) ; RUN ONE SET OF TESTS + N ZTMP + D ZLOAD^GPLUNIT("ZTMP","GPLCCR") + D ZTEST^GPLUNIT(.ZTMP,WHICH) + Q + ; +TLIST ; LIST THE TESTS + N ZTMP + D ZLOAD^GPLUNIT("ZTMP","GPLCCR") + D TLIST^GPLUNIT(.ZTMP) + Q + ; +;;> +;;> +;;>>>K GPL S GPL="" +;;>>>D CCRRPC^GPLCCR(.GPL,"2","PROBLEMS","","","") +;;>>?@GPL@(@GPL@(0))="" +;;> +;;>>>D ^%ZTER +;;>>>K GPL S GPL="" +;;>>>D CCRRPC^GPLCCR(.GPL,"2","CCR","","","") +;;>>?@GPL@(@GPL@(0))="" +;;> +;;>>>N TCCR +;;>>>D CCRRPC^GPLCCR(.TCCR,"2","CCR","","","") +;;>>>D ACTLST^GPLCCR("TCCR","ACTTEST") +;;> diff --git a/p/GPLCCR0.m b/p/GPLCCR0.m index 2bd76aa..c1e8d5f 100644 --- a/p/GPLCCR0.m +++ b/p/GPLCCR0.m @@ -1,625 +1,625 @@ -GPLCCR0 ; CCDCCR/GPL - CCR TEMPLATE AND ACCESS ROUTINES; 5/31/08 - ;;0.1;CCDCCR;nopatch;noreleasedate - W "This is a CCR TEMPLATE with processing routines",! - W ! - Q - ; -ZT(ZARY,BAT,LINE) ; private routine to add a line to the ZARY array - ; ZARY IS PASSED BY NAME - ; BAT is a string identifying the section - ; LINE is a test which will evaluate to true or false - ; I '$G(@ZARY) D - . S @ZARY@(0)=0 ; initially there are no elements - . W "GOT HERE LOADING "_LINE,! - N CNT ; count of array elements - S CNT=@ZARY@(0) ; contains array count - S CNT=CNT+1 ; increment count - S @ZARY@(CNT)=LINE ; put the line in the array - ; S @ZARY@(BAT,CNT)="" ; index the test by battery - S @ZARY@(0)=CNT ; update the array counter - Q - ; -ZLOAD(ZARY,ROUTINE) ; load tests into ZARY which is passed by reference - ; ZARY IS PASSED BY NAME - ; ZARY = name of the root, closed array format (e.g., "^TMP($J)") - ; ROUTINE = NAME OF THE ROUTINE - PASSED BY VALUE - K @ZARY S @ZARY="" - S @ZARY@(0)=0 ; initialize array count - N LINE,LABEL,BODY - N INTEST S INTEST=0 ; switch for in the TEMPLATE section - N SECTION S SECTION="[anonymous]" ; NO section LABEL - ; - N NUM F NUM=1:1 S LINE=$T(+NUM^@ROUTINE) Q:LINE="" D - . I LINE?." "1";".E S INTEST=0 ; leaving section - . I INTEST D ; within the section - . . I LINE?." "1";><".E D ; sub-section name found - . . . S SECTION=$P($P(LINE,";><",2),">",1) ; pull out name - . . I LINE?." "1";;".E D ; line found - . . . D ZT(ZARY,SECTION,$P(LINE,";;",2)) ; put the line in the array - Q - ; -LOAD(ARY) ; LOAD A CCR TEMPLATE INTO ARY PASSED BY NAME - D ZLOAD(ARY,"GPLCCR0") - ; ZWR @ARY - Q - ; -; +GPLCCR0 ; CCDCCR/GPL - CCR TEMPLATE AND ACCESS ROUTINES; 5/31/08 + ;;0.1;CCDCCR;nopatch;noreleasedate + W "This is a CCR TEMPLATE with processing routines",! + W ! + Q + ; +ZT(ZARY,BAT,LINE) ; private routine to add a line to the ZARY array + ; ZARY IS PASSED BY NAME + ; BAT is a string identifying the section + ; LINE is a test which will evaluate to true or false + ; I '$G(@ZARY) D + . S @ZARY@(0)=0 ; initially there are no elements + . W "GOT HERE LOADING "_LINE,! + N CNT ; count of array elements + S CNT=@ZARY@(0) ; contains array count + S CNT=CNT+1 ; increment count + S @ZARY@(CNT)=LINE ; put the line in the array + ; S @ZARY@(BAT,CNT)="" ; index the test by battery + S @ZARY@(0)=CNT ; update the array counter + Q + ; +ZLOAD(ZARY,ROUTINE) ; load tests into ZARY which is passed by reference + ; ZARY IS PASSED BY NAME + ; ZARY = name of the root, closed array format (e.g., "^TMP($J)") + ; ROUTINE = NAME OF THE ROUTINE - PASSED BY VALUE + K @ZARY S @ZARY="" + S @ZARY@(0)=0 ; initialize array count + N LINE,LABEL,BODY + N INTEST S INTEST=0 ; switch for in the TEMPLATE section + N SECTION S SECTION="[anonymous]" ; NO section LABEL + ; + N NUM F NUM=1:1 S LINE=$T(+NUM^@ROUTINE) Q:LINE="" D + . I LINE?." "1";".E S INTEST=0 ; leaving section + . I INTEST D ; within the section + . . I LINE?." "1";><".E D ; sub-section name found + . . . S SECTION=$P($P(LINE,";><",2),">",1) ; pull out name + . . I LINE?." "1";;".E D ; line found + . . . D ZT(ZARY,SECTION,$P(LINE,";;",2)) ; put the line in the array + Q + ; +LOAD(ARY) ; LOAD A CCR TEMPLATE INTO ARY PASSED BY NAME + D ZLOAD(ARY,"GPLCCR0") + ; ZWR @ARY + Q + ; +; diff --git a/p/GPLVITALS.m b/p/GPLVITALS.m index 4bbbaca..d60c5cb 100644 --- a/p/GPLVITALS.m +++ b/p/GPLVITALS.m @@ -1,15 +1,49 @@ -GPLVITALS ; CCDCCR/GPL - CCR/CCD PROCESSING FOR VITALS ; 6/6/08 - ;;0.1;CCDCCR;nopatch;noreleasedate -EXTRACT(VITXML,DFN,OUTXML) ; EXTRACT PROBLEMS INTO PROVIDED XML TEMPLATE - ; - ; VITXML AND OUTXML ARE PASSED BY NAME SO GLOBALS CAN BE USED - ; IVITXML WILL CONTAIN ONLY THE VITALS SECTION OF THE OVERALL TEMPLATE - ; - N VITALSTMP,I - S VITALSTMP="^TMP($J,""MISSINGVITALS"")" - ; ZWR @VITXML - D MISSING^GPLXPATH(VITXML,VITALSTMP) ; SEARCH XML FOR MISSING VARS - I @VITALSTMP@(0)>0 D ; IF THERE ARE MISSING VARS - MARKED AS @@X@@ - . W "VITALS MISSING ",! - . F I=1:1:@VITALSTMP@(0) W @VITALSTMP@(I),! - Q \ No newline at end of file +GPLVITALS ; CCDCCR/GPL - CCR/CCD PROCESSING FOR VITALS ; 6/6/08 + ;;0.1;CCDCCR;nopatch;noreleasedate +EXTRACT(VITXML,DFN,VITOUTXML) ; EXTRACT PROBLEMS INTO PROVIDED XML TEMPLATE + ; + ; VITXML AND OUTXML ARE PASSED BY NAME SO GLOBALS CAN BE USED + ; IVITXML WILL CONTAIN ONLY THE VITALS SECTION OF THE OVERALL TEMPLATE + ; + N VITRSLT,J,K,VITPTMP,X,VITVMAP,TBUF + D VITALS^ORQQVI(.VITRSLT,DFN,"","") + I '$D(VITRSLT(1)) W "ERROR RUNNINIG VITALS RPC",! Q + ;ZWR RPCRSLT + S VITTVMAP=$NA(^TMP($J,"VITALS")) + S VITTARYTMP=$NA(^TMP($J,"VITALARYTMP")) + F J=1:1:VITRSLT(1) D ; FOR EACH VITAL IN THE LIST + . I $D(VITRSLT(J)) D + . . S VITVMAP=$NA(@VITTVMAP@(J)) + . . K @VITVMAP + . . I DEBUG W "VMAP= ",VMAP,! + . . S VITPTMP=VITRSLT(J) ; PULL OUT VITAL FROM RPC RETURN ARRAY + . . S @VITVMAP@("DATAOBJECTID")="VITAL"_J ; UNIQUE OBJID FOR VITAL + . . I $P(VITPTMP,U,2)="HT" D + . . . S @VITVMAP@("HEIGHTWEIGHTDATATIME")=$P(VITPTMP,U,4) + . . . S @VITVMAP@("HEIGHTWEIGHTSOURCE")=$P(VITPTMP,U,7) + . . . S @VITVMAP@("HEIGHTSOURCEID")=$P(VITPTMP,U,1) + . . . S @VITVMAP@("HEIGHTINCHES")=$P(VITPTMP,U,3) + . . I $P(VITPTMP,U,2)="WT" D + . . . S @VITVMAP@("WEIGHTSOURCEID")=$P(VITPTMP,U,1) + . . . S @VITVMAP@("WEIGHTLBS")=$P(VITPTMP,U,3) + . . S VITARYTMP=$NA(@VITTARYTMP@(J)) + . . K @VITARYTMP + . . D MAP^GPLXPATH(VITXML,VITVMAP,VITARYTMP) + . . I J=1 D ; FIRST ONE IS JUST A COPY + . . . ; W "FIRST ONE",! + . . . D CP^GPLXPATH(VITARYTMP,VITOUTXML) + . . . ; W "OUTXML ",OUTXML,! + . . I J>1 D ; AFTER THE FIRST, INSERT INNER XML + . . . D INSINNER^GPLXPATH(VITOUTXML,VITARYTMP) + ;ZWR ^TMP($J,"VITALS",*) + ;ZWR ^TMP($J,"VITALARYTMP",*) ; SHOW THE RESULTS + ; W "OUT OF FOR LOOP.",! + ;ZWR + ; ZWR @OUTXML + ; $$HTML^DILF( + N VITTMP,I + D MISSING^GPLXPATH(VITXML,"VITTMP") ; SEARCH XML FOR MISSING VARS + I VITTMP(0)>0 D ; IF THERE ARE MISSING VARS - MARKED AS @@X@@ + . W "VITALS MISSING ",! + . F I=1:1:VITTMP(0) W VITTMP(I),! + Q diff --git a/p/GPLXPATH.m b/p/GPLXPATH.m index fe3d6b6..c07870d 100644 --- a/p/GPLXPATH.m +++ b/p/GPLXPATH.m @@ -1,521 +1,521 @@ -GPLXPATH ; CCDCCR/GPL - XPATH XML manipulation utilities; 6/1/08 - ;;0.2;CCDCCR;nopatch;noreleasedate - W "This is an XML XPATH utility library",! - W ! - Q - ; -OUTPUT(OUTARY,OUTNAME,OUTDIR) ; WRITE AN ARRAY TO A FILE - ; - N Y - S Y=$$GTF^%ZISH(OUTARY,$QL(OUTARY),OUTDIR,OUTNAME) - I Y W "WROTE FILE: ",OUTNAME," TO ",OUTDIR,! - ; $NA(^TMP(14216,"FILE",0)),3,"/home/wvehr3","test.xml") - Q - ; -PUSH(STK,VAL) ; pushs VAL onto STK and updates STK(0) - ; VAL IS A STRING AND STK IS PASSED BY NAME - ; - I '$D(@STK@(0)) S @STK@(0)=0 ; IF THE ARRAY IS EMPTY, INITIALIZE - S @STK@(0)=@STK@(0)+1 ; INCREMENT ARRAY DEPTH - S @STK@(@STK@(0))=VAL ; PUT VAL A THE END OF THE ARRAY - Q - ; -POP(STK,VAL) ; POPS THE LAST VALUE OFF THE STK AND RETURNS IT IN VAL - ; VAL AND STK ARE PASSED BY REFERENCE - ; - I @STK@(0)<1 S VAL="",@STK@(0)=0 Q ; IF ARRAY IS EMPTY - I @STK@(0)>0 D - . S VAL=@STK@(@STK@(0)) - . K @STK@(@STK@(0)) - . S @STK@(0)=@STK@(0)-1 ; NEW DEPTH OF THE ARRAY - Q - ; -MKMDX(STK,RTN) ; MAKES A MUMPS INDEX FROM THE ARRAY STK - ; RTN IS SET TO //FIRST/SECOND/THIRD" FOR THREE ARRAY ELEMENTS - S RTN="" - N I - ; W "STK= ",STK,! - I @STK@(0)>0 D ; IF THE ARRAY IS NOT EMPTY - . S RTN="//"_@STK@(1) ; FIRST ELEMENT NEEDS NO SEMICOLON - . I @STK@(0)>1 D ; SUBSEQUENT ELEMENTS NEED A SEMICOLON - . . F I=2:1:@STK@(0) S RTN=RTN_"/"_@STK@(I) - Q - ; -XNAME(ISTR) ; FUNCTION TO EXTRACT A NAME FROM AN XML FRAG - ; AND WILL RETURN NAME - ; ISTR IS PASSED BY VALUE - N CUR,TMP - I ISTR?.E1"<".E D ; STRIP OFF LEFT BRACKET - . S TMP=$P(ISTR,"<",2) - I TMP?1"/".E D ; ALSO STRIP OFF SLASH IF PRESENT IE - . S TMP=$P(TMP,"/",2) - S CUR=$P(TMP,">",1) ; EXTRACT THE NAME - ; W "CUR= ",CUR,! - I CUR?.1"_"1.A1" ".E D ; CONTAINS A BLANK IE NAME ID=TEST> - . S CUR=$P(CUR," ",1) ; STRIP OUT BLANK AND AFTER - ; W "CUR2= ",CUR,! - Q CUR - ; -INDEX(ZXML) ; parse the XML in ZXML and produce an XPATH index - ; ex. ZXML(FIRST,SECOND,THIRD,FOURTH)=FIRSTLINE^LASTLINE - ; WHERE FIRSTLINE AND LASTLINE ARE THE BEGINNING AND ENDING OF THE - ; XML SECTION - ; ZXML IS PASSED BY NAME - N I,LINE,FIRST,LAST,CUR,TMP,MDX,FOUND - N GPLSTK ; LEAVE OUT FOR DEBUGGING - I '$D(@ZXML@(0)) D ; NO XML PASSED - . W "ERROR IN XML FILE",! - S GPLSTK(0)=0 ; INITIALIZE STACK - F I=1:1:@ZXML@(0) D ; PROCESS THE ENTIRE ARRAY - . S LINE=@ZXML@(I) - . ;W LINE,! - . S FOUND=0 ; INTIALIZED FOUND FLAG - . I LINE?.E1"".E) D - . . . ; THIS IS THE CASE THERE SECTION BEGINS AND ENDS ON THE SAME LINE - . . . ; W "FOUND ",LINE,! - . . . S FOUND=1 ; SET FOUND FLAG - . . . S CUR=$$XNAME(LINE) ; EXTRACT THE NAME - . . . D PUSH("GPLSTK",CUR) ; ADD TO THE STACK - . . . D MKMDX("GPLSTK",.MDX) ; GENERATE THE M INDEX - . . . ; W "MDX=",MDX,! - . . . I $D(@ZXML@(MDX)) D ; IN THE INDEX, IS A MULTIPLE - . . . . S $P(@ZXML@(MDX),"^",2)=I ; UPDATE LAST LINE NUMBER - . . . I '$D(@ZXML@(MDX)) D ; NOT IN THE INDEX, IS NOT A MULTIPLE - . . . . S @ZXML@(MDX)=I_"^"_I ; ADD INDEX ENTRY-FIRST AND LAST LINE - . . . D POP("GPLSTK",.TMP) ; REMOVE FROM STACK - . I FOUND'=1 D ; THE LINE DOESN'T CONTAIN THE START AND END OF A SEC - . . I LINE?.E1"") D ; BEGINNING OF A SECTION - . . . ; W "FOUND ",LINE,! - . . . S FOUND=1 ; SET FOUND FLAG - . . . S CUR=$$XNAME(LINE) ; EXTRACT THE NAME - . . . D PUSH("GPLSTK",CUR) ; ADD TO THE STACK - . . . D MKMDX("GPLSTK",.MDX) ; GENERATE THE M INDEX - . . . ; W "MDX=",MDX,! - . . . I $D(@ZXML@(MDX)) D ; IN THE INDEX, IS A MULTIPLE - . . . . S $P(@ZXML@(MDX),"^",2)=I ; UPDATE LAST LINE NUMBER - . . . I '$D(@ZXML@(MDX)) D ; NOT IN THE INDEX, IS NOT A MULTIPLE - . . . . S @ZXML@(MDX)=I_"^" ; INSERT INTO THE INDEX - S @ZXML@("INDEXED")="" - S @ZXML@("//")="1^"_@ZXML@(0) ; ROOT XPATH - Q - ; -QUERY(IARY,XPATH,OARY) ; RETURNS THE XML ARRAY MATCHING THE XPATH EXPRESSION - ; XPATH IS OF THE FORM "//FIRST/SECOND/THIRD" - ; IARY AND OARY ARE PASSED BY NAME - I '$D(@IARY@("INDEXED")) D ; INDEX IS NOT PRESENT IN IARY - . D INDEX(IARY) ; GENERATE AN INDEX FOR THE XML - N FIRST,LAST ; FIRST AND LAST LINES OF ARRAY TO RETURN - N TMP,I,J,QXPATH - S FIRST=1 - S LAST=@IARY@(0) ; FIRST AND LAST DEFAULT TO ROOT - I XPATH'="//" D ; NOT A ROOT QUERY - . S TMP=@IARY@(XPATH) ; LOOK UP LINE VALUES - . S FIRST=$P(TMP,"^",1) - . S LAST=$P(TMP,"^",2) - K @OARY - S @OARY@(0)=+LAST-FIRST+1 - S J=1 - FOR I=FIRST:1:LAST D - . S @OARY@(J)=@IARY@(I) ; COPY THE LINE TO OARY - . S J=J+1 - ; ZWR OARY - Q - ; -XF(IDX,XPATH) ; EXTRINSIC TO RETURN THE STARTING LINE FROM AN XPATH - ; INDEX WITH TWO PIECES START^FINISH - ; IDX IS PASSED BY NAME - Q $P(@IDX@(XPATH),"^",1) - ; -XL(IDX,XPATH) ; EXTRINSIC TO RETURN THE LAST LINE FROM AN XPATH - ; INDEX WITH TWO PIECES START^FINISH - ; IDX IS PASSED BY NAME - Q $P(@IDX@(XPATH),"^",2) - ; -START(ISTR) ; EXTRINSIC TO RETURN THE STARTING LINE FROM AN INDEX - ; TYPE STRING WITH THREE PIECES ARRAY;START;FINISH - ; COMPANION TO FINISH ; IDX IS PASSED BY NAME - Q $P(ISTR,";",2) - ; -FINISH(ISTR) ; EXTRINSIC TO RETURN THE LAST LINE FROM AN INDEX - ; TYPE STRING WITH THREE PIECES ARRAY;START;FINISH - Q $P(ISTR,";",3) - ; -ARRAY(ISTR) ; EXTRINSIC TO RETURN THE ARRAY REFERENCE FROM AN INDEX - ; TYPE STRING WITH THREE PIECES ARRAY;START;FINISH - Q $P(ISTR,";",1) - ; -BUILD(BLIST,BDEST) ; A COPY MACHINE THAT TAKE INSTRUCTIONS IN ARRAY BLIST - ; WHICH HAVE ARRAY;START;FINISH AND COPIES THEM TO DEST - ; DEST IS CLEARED TO START - ; USES PUSH TO DO THE COPY - N I - K @BDEST - F I=1:1:@BLIST@(0) D ; FOR EACH INSTRUCTION IN BLIST - . N J,ATMP - . S ATMP=$$ARRAY(@BLIST@(I)) - . I DEBUG W "ATMP=",ATMP,! - . I DEBUG W @BLIST@(I),! - . F J=$$START(@BLIST@(I)):1:$$FINISH(@BLIST@(I)) D ; - . . ; FOR EACH LINE IN THIS INSTR - . . I DEBUG W "BDEST= ",BDEST,! - . . I DEBUG W "ATMP= ",@ATMP@(J),! - . . D PUSH(BDEST,@ATMP@(J)) - Q - ; -QUEUE(BLST,ARRAY,FIRST,LAST) ; ADD AN ENTRY TO A BLIST - ; - I DEBUG W "QUEUEING ",BLST,! - D PUSH(BLST,ARRAY_";"_FIRST_";"_LAST) - Q - ; -CP(CPSRC,CPDEST) ; COPIES CPSRC TO CPDEST BOTH PASSED BY NAME - ; KILLS CPDEST FIRST - N CPINSTR - I DEBUG W "MADE IT TO COPY",CPSRC,CPDEST,! - I @CPSRC@(0)<1 D ; BAD LENGTH - . W "ERROR IN COPY BAD SOURCE LENGTH: ",CPSRC,! - . Q - ; I '$D(@CPDEST@(0)) S @CPDEST@(0)=0 ; IF THE DEST IS EMPTY, INITIALIZE - D QUEUE("CPINSTR",CPSRC,1,@CPSRC@(0)) ; BLIST FOR ENTIRE ARRAY - D BUILD("CPINSTR",CPDEST) - Q - ; -QOPEN(QOBLIST,QOXML,QOXPATH) ; ADD ALL BUT THE LAST LINE OF QOXML TO QOBLIST - ; WARNING NEED TO DO QCLOSE FOR SAME XML BEFORE CALLING BUILD - ; QOXPATH IS OPTIONAL - IF PROVIDED, WILL OPEN INSIDE THE XPATH POINT - ; USED TO INSERT CHILDREN NODES - I @QOXML@(0)<1 D ; MALFORMED XML - . W "MALFORMED XML PASSED TO QOPEN: ",QOXML,! - . Q - I DEBUG W "DOING QOPEN",! - N S1,E1,QOT,QOTMP - S S1=1 ; OPEN FROM THE BEGINNING OF THE XML - I $D(QOXPATH) D ; XPATH PROVIDED - . D QUERY(QOXML,QOXPATH,"QOT") ; INSURE INDEX - . S E1=$P(@QOXML@(QOXPATH),"^",2)-1 - I '$D(QOXPATH) D ; NO XPATH PROVIDED, OPEN AT ROOT - . S E1=@QOXML@(0)-1 - D QUEUE(QOBLIST,QOXML,S1,E1) - ; S QOTMP=QOXML_"^"_S1_"^"_E1 - ; D PUSH(QOBLIST,QOTMP) - Q - ; -QCLOSE(QCBLIST,QCXML,QCXPATH) ; CLOSE XML AFTER A QOPEN - ; ADDS THE LIST LINE OF QCXML TO QCBLIST - ; USED TO FINISH INSERTING CHILDERN NODES - ; QCXPATH IS OPTIONAL - IF PROVIDED, WILL CLOSE UNTIL THE END - ; IF QOPEN WAS CALLED WITH XPATH, QCLOSE SHOULD BE TOO - I @QCXML@(0)<1 D ; MALFORMED XML - . W "MALFORMED XML PASSED TO QCLOSE: ",QCXML,! - I DEBUG W "GOING TO CLOSE",! - N S1,E1,QCT,QCTMP - S E1=@QCXML@(0) ; CLOSE UNTIL THE END OF THE XML - I $D(QCXPATH) D ; XPATH PROVIDED - . D QUERY(QCXML,QCXPATH,"QCT") ; INSURE INDEX - . S S1=$P(@QCXML@(QCXPATH),"^",2) ; REMAINING XML - I '$D(QCXPATH) D ; NO XPATH PROVIDED, CLOSE AT ROOT - . S S1=@QCXML@(0) - D QUEUE(QCBLIST,QCXML,S1,E1) - ; D PUSH(QCBLIST,QCXML_";"_S1_";"_E1) - Q - ; -INSERT(INSXML,INSNEW,INSXPATH) ; INSERT INSNEW INTO INSXML AT THE - ; INSXPATH XPATH POINT INSXPATH IS OPTIONAL - IF IT IS - ; OMITTED, INSERTION WILL BE AT THE ROOT - ; NOTE INSERT IS NON DESTRUCTIVE AND WILL ADD THE NEW - ; XML AT THE END OF THE XPATH POINT - ; INSXML AND INSNEW ARE PASSED BY NAME INSXPATH IS A VALUE - N INSBLD,INSTMP - I DEBUG W "DOING INSERT ",INSXML,INSNEW,INSXPATH,! - I DEBUG F G1=1:1:@INSXML@(0) W @INSXML@(G1),! - I '$D(@INSXML@(0)) D Q ; INSERT INTO AN EMPTY ARRAY - . D CP^GPLXPATH(INSNEW,INSXML) ; JUST COPY INTO THE OUTPUT - I $D(@INSXML@(0)) D ; IF ORIGINAL ARRAY IS NOT EMPTY - . I $D(INSXPATH) D ; XPATH PROVIDED - . . D QOPEN("INSBLD",INSXML,INSXPATH) ; COPY THE BEFORE - . . I DEBUG ZWR INSBLD - . I '$D(INSXPATH) D ; NO XPATH PROVIDED, OPEN AT ROOT - . . D QOPEN("INSBLD",INSXML,"//") ; OPEN WITH ROOT XPATH - . D QUEUE("INSBLD",INSNEW,1,@INSNEW@(0)) ; COPY IN NEW XML - . I $D(INSXPATH) D ; XPATH PROVIDED - . . D QCLOSE("INSBLD",INSXML,INSXPATH) ; CLOSE WITH XPATH - . I '$D(INSXPATH) D ; NO XPATH PROVIDED, CLOSE AT ROOT - . . D QCLOSE("INSBLD",INSXML,"//") ; CLOSE WITH ROOT XPATH - . D BUILD("INSBLD","INSTMP") ; PUT RESULTS IN INDEST - . D CP^GPLXPATH("INSTMP",INSXML) ; COPY BUFFER TO SOURCE - Q - ; -INSINNER(INNXML,INNNEW,INNXPATH) ; INSERT THE INNER XML OF INNNEW - ; INTO INNXML AT THE INNXPATH XPATH POINT - ; - N INNBLD,UXPATH - N INNTBUF - S INNTBUF=$NA(^TMP($J,"INNTBUF")) - I '$D(INNXPATH) D ; XPATH NOT PASSED - . S UXPATH="//" ; USE ROOT XPATH - I $D(INNXPATH) S UXPATH=INNXPATH ; USE THE XPATH THAT'S PASSED - I '$D(@INNXML@(0)) D ; INNXML IS EMPTY - . D QUEUE^GPLXPATH("INNBLD",INNNEW,2,@INNNEW@(0)-1) ; JUST INNER XML - . D BUILD("INNBLD",INNXML) - I @INNXML@(0)>0 D ; NOT EMPTY - . D QOPEN("INNBLD",INNXML,UXPATH) ; - . D QUEUE("INNBLD",INNNEW,2,@INNNEW@(0)-1) ; JUST INNER XML - . D QCLOSE("INNBLD",INNXML,UXPATH) - . D BUILD("INNBLD",INNTBUF) ; BUILD TO BUFFER - . D CP(INNTBUF,INNXML) ; COPY BUFFER TO DEST - Q - ; -REPLACE(REXML,RENEW,REXPATH) ; REPLACE THE XML AT THE XPATH POINT - ; WITH RENEW - NOTE THIS WILL DELETE WHAT WAS THERE BEFORE - ; REXML AND RENEW ARE PASSED BY NAME XPATH IS A VALUE - ; THE DELETED XML IS PUT IN ^TMP($J,"REPLACE_OLD") - N REBLD,XFIRST,XLAST,OLD,XNODE,RETMP - S OLD=$NA(^TMP($J,"REPLACE_OLD")) - D QUERY(REXML,REXPATH,OLD) ; CREATE INDEX, TEST XPATH, MAKE OLD - S XNODE=@REXML@(REXPATH) ; PULL OUT FIRST AND LAST LINE PTRS - S XFIRST=$P(XNODE,"^",1) - S XLAST=$P(XNODE,"^",2) - D QUEUE("REBLD",REXML,1,XFIRST) ; THE BEFORE - I RENEW'="" D ; NEW XML IS NOT NULL - . D QUEUE("REBLD",RENEW,1,@RENEW@(0)) ; THE NEW - D QUEUE("REBLD",REXML,XLAST,@REXML@(0)) ; THE REST - I DEBUG W "REPALCE PREBUILD",! - I DEBUG ZWR REBLD - D BUILD("REBLD","RTMP") - K @REXML ; KILL WHAT WAS THERE - D CP("RTMP",REXML) ; COPY IN THE RESULT - Q - ; -MISSING(IXML,OARY) ; SEARTH THROUGH INXLM AND PUT ANY @@X@@ VARS IN OARY - ; W "Reporting on the missing",! - ; W OARY - I '$D(@IXML@(0)) W "MALFORMED XML PASSED TO MISSING",! Q - N I - S @OARY@(0)=0 ; INITIALIZED MISSING COUNT - F I=1:1:@IXML@(0) D ; LOOP THROUGH WHOLE ARRAY - . I @IXML@(I)?.E1"@@".E D ; MISSING VARIABLE HERE - . . D PUSH^GPLXPATH(OARY,$P(@IXML@(I),"@@",2)) ; ADD TO OUTARY - . . Q - Q - ; -MAP(IXML,INARY,OXML) ; SUBSTITUTE @@X@@ VARS IN IXML WITH VALUES IN INARY - ; AND PUT THE RESULTS IN OXML - I '$D(@IXML@(0)) W "MALFORMED XML PASSED TO MAP",! Q - I $O(@INARY@(""))="" W "EMPTY ARRAY PASSED TO MAP",! Q - N I,TNAM,TVAL - S @OXML@(0)=@IXML@(0) ; TOTAL LINES IN OUTPUT - F I=1:1:@OXML@(0) D ; LOOP THROUGH WHOLE ARRAY - . S @OXML@(I)=@IXML@(I) ; COPY THE LINE TO OUTPUT - . I @OXML@(I)?.E1"@@".E D ; IS THERE A VARIABLE HERE? - . . S TNAM=$P(@OXML@(I),"@@",2) ; EXTRACT THE VARIABLE NAME - . . I $D(@INARY@(TNAM)) D ; IS THE VARIABLE IN THE MAP? - . . . S TVAL=@INARY@(TNAM) ; PULL OUT MAPPED VALUE - . . . S @OXML@(I)=$P(@OXML@(I),"@@",1)_TVAL_$P(@OXML@(I),"@@",3) ;MAPIT - W "MAPPED",! - Q - ; -PARY(GLO) ;PRINT AN ARRAY - N I - F I=1:1:@GLO@(0) W @GLO@(I),! - Q - ; -TEST ; Run all the test cases - D TESTALL^GPLUNIT("GPLXPATH") - Q - ; -OLDTEST ; RUN ALL THE TEST CASES - N ZTMP - D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") - D ZTEST^GPLUNIT(.ZTMP,"ALL") - W "PASSED: ",TPASSED,! - W "FAILED: ",TFAILED,! - W ! - ; W "THE TESTS!",! - ; ZWR ZTMP - Q - ; -ZTEST(WHICH) ; RUN ONE SET OF TESTS - N ZTMP - S DEBUG=1 - D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") - D ZTEST^GPLUNIT(.ZTMP,WHICH) - Q - ; -TLIST ; LIST THE TESTS - N ZTMP - D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") - D TLIST^GPLUNIT(.ZTMP) - Q - ; -;;> -;;> -;;>>>K GPL S GPL="" -;;>>>D PUSH^GPLXPATH("GPL","FIRST") -;;>>>D PUSH^GPLXPATH("GPL","SECOND") -;;>>>D PUSH^GPLXPATH("GPL","THIRD") -;;>>>D PUSH^GPLXPATH("GPL","FOURTH") -;;>>?GPL(0)=4 -;;> -;;>>>K GXML S GXML="" -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","@@DATA1@@") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","@@DATA2@@") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;> -;;>>>K GXML S GXML="" -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","DATA1") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","DATA2") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","<_SECOND>") -;;>>>D PUSH^GPLXPATH("GXML","DATA3") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;>>>D PUSH^GPLXPATH("GXML","") -;;> -;;>>>D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") -;;>>>D ZTEST^GPLUNIT(.ZTMP,"INIT") -;;>>?GPL(GPL(0))="FOURTH" -;;>>>D POP^GPLXPATH("GPL",.GX) -;;>>?GX="FOURTH" -;;>>?GPL(GPL(0))="THIRD" -;;>>>D POP^GPLXPATH("GPL",.GX) -;;>>?GX="THIRD" -;;>>?GPL(GPL(0))="SECOND" -;;> -;;>>>D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") -;;>>>D ZTEST^GPLUNIT(.ZTMP,"INIT") -;;>>>S GX="" -;;>>>D MKMDX^GPLXPATH("GPL",.GX) -;;>>?GX="//FIRST/SECOND/THIRD/FOURTH" -;;> -;;>>?$$XNAME^GPLXPATH("DATA1")="FOURTH" -;;>>?$$XNAME^GPLXPATH("")="SIXTH" -;;>>?$$XNAME^GPLXPATH("")="THIRD" -;;> -;;>>>D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") -;;>>>D ZTEST^GPLUNIT(.ZTMP,"INITXML") -;;>>>D INDEX^GPLXPATH("GXML") -;;>>?GXML("//FIRST/SECOND")="2^12" -;;>>?GXML("//FIRST/SECOND/THIRD")="3^9" -;;>>?GXML("//FIRST/SECOND/THIRD/FIFTH")="5^7" -;;>>?GXML("//FIRST/SECOND/THIRD/FOURTH")="4^4" -;;>>?GXML("//FIRST/SECOND/THIRD/SIXTH")="8^8" -;;>>?GXML("//FIRST/SECOND")="2^12" -;;>>?GXML("//FIRST")="1^13" -;;> -;;>>>D ZTEST^GPLXPATH("INITXML2") -;;>>>D INDEX^GPLXPATH("GXML") -;;>>?GXML("//FIRST/SECOND")="2^12" -;;>>?GXML("//FIRST/SECOND/_SECOND")="9^11" -;;>>?GXML("//FIRST/SECOND/_SECOND/FOURTH")="10^10" -;;>>?GXML("//FIRST/SECOND/THIRD")="3^8" -;;>>?GXML("//FIRST/SECOND/THIRD/FOURTH")="4^7" -;;>>?GXML("//FIRST")="1^13" -;;> -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>S OUTARY="^TMP($J,""MISSINGTEST"")" -;;>>>D MISSING^GPLXPATH("GXML",OUTARY) -;;>>?@OUTARY@(1)="DATA1" -;;>>?@OUTARY@(2)="DATA2" -;;> -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>S MAPARY="^TMP($J,""MAPVALUES"")" -;;>>>S OUTARY="^TMP($J,""MAPTEST"")" -;;>>>S @MAPARY@("DATA2")="VALUE2" -;;>>>D MAP^GPLXPATH("GXML",MAPARY,OUTARY) -;;>>?@OUTARY@(6)="VALUE2" -;;> -;;>>>D QUEUE^GPLXPATH("BTLIST","GXML",2,3) -;;>>>D QUEUE^GPLXPATH("BTLIST","GXML",4,5) -;;>>?$P(BTLIST(2),";",2)=4 -;;> -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD/FOURTH","G2") -;;>>>D ZTEST^GPLXPATH("QUEUE") -;;>>>D BUILD^GPLXPATH("BTLIST","G3") -;;> -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D CP^GPLXPATH("GXML","G2") -;;>>?G2(0)=13 -;;> -;;>>>K G2,GBL -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QOPEN^GPLXPATH("GBL","GXML") -;;>>?$P(GBL(1),";",3)=12 -;;>>>D BUILD^GPLXPATH("GBL","G2") -;;>>?G2(G2(0))="" -;;> -;;>>>K G2,GBL -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QOPEN^GPLXPATH("GBL","GXML","//FIRST/SECOND") -;;>>?$P(GBL(1),";",3)=11 -;;>>>D BUILD^GPLXPATH("GBL","G2") -;;>>?G2(G2(0))="" -;;> -;;>>>K G2,GBL -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QCLOSE^GPLXPATH("GBL","GXML") -;;>>?$P(GBL(1),";",3)=13 -;;>>>D BUILD^GPLXPATH("GBL","G2") -;;>>?G2(G2(0))="" -;;> -;;>>>K G2,GBL -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QCLOSE^GPLXPATH("GBL","GXML","//FIRST/SECOND/THIRD") -;;>>?$P(GBL(1),";",3)=13 -;;>>>D BUILD^GPLXPATH("GBL","G2") -;;>>?G2(G2(0))="" -;;>>?G2(1)="" -;;> -;;>>>K G2,GBL,G3,G4 -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD/FIFTH","G2") -;;>>>D INSERT^GPLXPATH("GXML","G2","//FIRST/SECOND/THIRD") -;;>>>D INSERT^GPLXPATH("G3","G2","//") -;;>>?G2(1)=GXML(9) -;;> -;;>>>K G2,GBL,G3 -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD/FIFTH","G2") -;;>>>D REPLACE^GPLXPATH("GXML","G2","//FIRST/SECOND") -;;>>?GXML(3)="" -;;> -;;>>>K GXML,G2,GBL,G3 -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD","G2") -;;>>>D INSINNER^GPLXPATH("GXML","G2","//FIRST/SECOND/THIRD") -;;>>?GXML(10)="" -;;> -;;>>>K GXML,G2,GBL,G3 -;;>>>D ZTEST^GPLXPATH("INITXML") -;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD","G2") -;;>>>D INSINNER^GPLXPATH("G2","G2") -;;>>?G2(8)="" -;;> +GPLXPATH ; CCDCCR/GPL - XPATH XML manipulation utilities; 6/1/08 + ;;0.2;CCDCCR;nopatch;noreleasedate + W "This is an XML XPATH utility library",! + W ! + Q + ; +OUTPUT(OUTARY,OUTNAME,OUTDIR) ; WRITE AN ARRAY TO A FILE + ; + N Y + S Y=$$GTF^%ZISH(OUTARY,$QL(OUTARY),OUTDIR,OUTNAME) + I Y W "WROTE FILE: ",OUTNAME," TO ",OUTDIR,! + ; $NA(^TMP(14216,"FILE",0)),3,"/home/wvehr3","test.xml") + Q + ; +PUSH(STK,VAL) ; pushs VAL onto STK and updates STK(0) + ; VAL IS A STRING AND STK IS PASSED BY NAME + ; + I '$D(@STK@(0)) S @STK@(0)=0 ; IF THE ARRAY IS EMPTY, INITIALIZE + S @STK@(0)=@STK@(0)+1 ; INCREMENT ARRAY DEPTH + S @STK@(@STK@(0))=VAL ; PUT VAL A THE END OF THE ARRAY + Q + ; +POP(STK,VAL) ; POPS THE LAST VALUE OFF THE STK AND RETURNS IT IN VAL + ; VAL AND STK ARE PASSED BY REFERENCE + ; + I @STK@(0)<1 S VAL="",@STK@(0)=0 Q ; IF ARRAY IS EMPTY + I @STK@(0)>0 D + . S VAL=@STK@(@STK@(0)) + . K @STK@(@STK@(0)) + . S @STK@(0)=@STK@(0)-1 ; NEW DEPTH OF THE ARRAY + Q + ; +MKMDX(STK,RTN) ; MAKES A MUMPS INDEX FROM THE ARRAY STK + ; RTN IS SET TO //FIRST/SECOND/THIRD" FOR THREE ARRAY ELEMENTS + S RTN="" + N I + ; W "STK= ",STK,! + I @STK@(0)>0 D ; IF THE ARRAY IS NOT EMPTY + . S RTN="//"_@STK@(1) ; FIRST ELEMENT NEEDS NO SEMICOLON + . I @STK@(0)>1 D ; SUBSEQUENT ELEMENTS NEED A SEMICOLON + . . F I=2:1:@STK@(0) S RTN=RTN_"/"_@STK@(I) + Q + ; +XNAME(ISTR) ; FUNCTION TO EXTRACT A NAME FROM AN XML FRAG + ; AND WILL RETURN NAME + ; ISTR IS PASSED BY VALUE + N CUR,TMP + I ISTR?.E1"<".E D ; STRIP OFF LEFT BRACKET + . S TMP=$P(ISTR,"<",2) + I TMP?1"/".E D ; ALSO STRIP OFF SLASH IF PRESENT IE + . S TMP=$P(TMP,"/",2) + S CUR=$P(TMP,">",1) ; EXTRACT THE NAME + ; W "CUR= ",CUR,! + I CUR?.1"_"1.A1" ".E D ; CONTAINS A BLANK IE NAME ID=TEST> + . S CUR=$P(CUR," ",1) ; STRIP OUT BLANK AND AFTER + ; W "CUR2= ",CUR,! + Q CUR + ; +INDEX(ZXML) ; parse the XML in ZXML and produce an XPATH index + ; ex. ZXML(FIRST,SECOND,THIRD,FOURTH)=FIRSTLINE^LASTLINE + ; WHERE FIRSTLINE AND LASTLINE ARE THE BEGINNING AND ENDING OF THE + ; XML SECTION + ; ZXML IS PASSED BY NAME + N I,LINE,FIRST,LAST,CUR,TMP,MDX,FOUND + N GPLSTK ; LEAVE OUT FOR DEBUGGING + I '$D(@ZXML@(0)) D ; NO XML PASSED + . W "ERROR IN XML FILE",! + S GPLSTK(0)=0 ; INITIALIZE STACK + F I=1:1:@ZXML@(0) D ; PROCESS THE ENTIRE ARRAY + . S LINE=@ZXML@(I) + . ;W LINE,! + . S FOUND=0 ; INTIALIZED FOUND FLAG + . I LINE?.E1"".E) D + . . . ; THIS IS THE CASE THERE SECTION BEGINS AND ENDS ON THE SAME LINE + . . . ; W "FOUND ",LINE,! + . . . S FOUND=1 ; SET FOUND FLAG + . . . S CUR=$$XNAME(LINE) ; EXTRACT THE NAME + . . . D PUSH("GPLSTK",CUR) ; ADD TO THE STACK + . . . D MKMDX("GPLSTK",.MDX) ; GENERATE THE M INDEX + . . . ; W "MDX=",MDX,! + . . . I $D(@ZXML@(MDX)) D ; IN THE INDEX, IS A MULTIPLE + . . . . S $P(@ZXML@(MDX),"^",2)=I ; UPDATE LAST LINE NUMBER + . . . I '$D(@ZXML@(MDX)) D ; NOT IN THE INDEX, IS NOT A MULTIPLE + . . . . S @ZXML@(MDX)=I_"^"_I ; ADD INDEX ENTRY-FIRST AND LAST LINE + . . . D POP("GPLSTK",.TMP) ; REMOVE FROM STACK + . I FOUND'=1 D ; THE LINE DOESN'T CONTAIN THE START AND END OF A SEC + . . I LINE?.E1"") D ; BEGINNING OF A SECTION + . . . ; W "FOUND ",LINE,! + . . . S FOUND=1 ; SET FOUND FLAG + . . . S CUR=$$XNAME(LINE) ; EXTRACT THE NAME + . . . D PUSH("GPLSTK",CUR) ; ADD TO THE STACK + . . . D MKMDX("GPLSTK",.MDX) ; GENERATE THE M INDEX + . . . ; W "MDX=",MDX,! + . . . I $D(@ZXML@(MDX)) D ; IN THE INDEX, IS A MULTIPLE + . . . . S $P(@ZXML@(MDX),"^",2)=I ; UPDATE LAST LINE NUMBER + . . . I '$D(@ZXML@(MDX)) D ; NOT IN THE INDEX, IS NOT A MULTIPLE + . . . . S @ZXML@(MDX)=I_"^" ; INSERT INTO THE INDEX + S @ZXML@("INDEXED")="" + S @ZXML@("//")="1^"_@ZXML@(0) ; ROOT XPATH + Q + ; +QUERY(IARY,XPATH,OARY) ; RETURNS THE XML ARRAY MATCHING THE XPATH EXPRESSION + ; XPATH IS OF THE FORM "//FIRST/SECOND/THIRD" + ; IARY AND OARY ARE PASSED BY NAME + I '$D(@IARY@("INDEXED")) D ; INDEX IS NOT PRESENT IN IARY + . D INDEX(IARY) ; GENERATE AN INDEX FOR THE XML + N FIRST,LAST ; FIRST AND LAST LINES OF ARRAY TO RETURN + N TMP,I,J,QXPATH + S FIRST=1 + S LAST=@IARY@(0) ; FIRST AND LAST DEFAULT TO ROOT + I XPATH'="//" D ; NOT A ROOT QUERY + . S TMP=@IARY@(XPATH) ; LOOK UP LINE VALUES + . S FIRST=$P(TMP,"^",1) + . S LAST=$P(TMP,"^",2) + K @OARY + S @OARY@(0)=+LAST-FIRST+1 + S J=1 + FOR I=FIRST:1:LAST D + . S @OARY@(J)=@IARY@(I) ; COPY THE LINE TO OARY + . S J=J+1 + ; ZWR OARY + Q + ; +XF(IDX,XPATH) ; EXTRINSIC TO RETURN THE STARTING LINE FROM AN XPATH + ; INDEX WITH TWO PIECES START^FINISH + ; IDX IS PASSED BY NAME + Q $P(@IDX@(XPATH),"^",1) + ; +XL(IDX,XPATH) ; EXTRINSIC TO RETURN THE LAST LINE FROM AN XPATH + ; INDEX WITH TWO PIECES START^FINISH + ; IDX IS PASSED BY NAME + Q $P(@IDX@(XPATH),"^",2) + ; +START(ISTR) ; EXTRINSIC TO RETURN THE STARTING LINE FROM AN INDEX + ; TYPE STRING WITH THREE PIECES ARRAY;START;FINISH + ; COMPANION TO FINISH ; IDX IS PASSED BY NAME + Q $P(ISTR,";",2) + ; +FINISH(ISTR) ; EXTRINSIC TO RETURN THE LAST LINE FROM AN INDEX + ; TYPE STRING WITH THREE PIECES ARRAY;START;FINISH + Q $P(ISTR,";",3) + ; +ARRAY(ISTR) ; EXTRINSIC TO RETURN THE ARRAY REFERENCE FROM AN INDEX + ; TYPE STRING WITH THREE PIECES ARRAY;START;FINISH + Q $P(ISTR,";",1) + ; +BUILD(BLIST,BDEST) ; A COPY MACHINE THAT TAKE INSTRUCTIONS IN ARRAY BLIST + ; WHICH HAVE ARRAY;START;FINISH AND COPIES THEM TO DEST + ; DEST IS CLEARED TO START + ; USES PUSH TO DO THE COPY + N I + K @BDEST + F I=1:1:@BLIST@(0) D ; FOR EACH INSTRUCTION IN BLIST + . N J,ATMP + . S ATMP=$$ARRAY(@BLIST@(I)) + . I DEBUG W "ATMP=",ATMP,! + . I DEBUG W @BLIST@(I),! + . F J=$$START(@BLIST@(I)):1:$$FINISH(@BLIST@(I)) D ; + . . ; FOR EACH LINE IN THIS INSTR + . . I DEBUG W "BDEST= ",BDEST,! + . . I DEBUG W "ATMP= ",@ATMP@(J),! + . . D PUSH(BDEST,@ATMP@(J)) + Q + ; +QUEUE(BLST,ARRAY,FIRST,LAST) ; ADD AN ENTRY TO A BLIST + ; + I DEBUG W "QUEUEING ",BLST,! + D PUSH(BLST,ARRAY_";"_FIRST_";"_LAST) + Q + ; +CP(CPSRC,CPDEST) ; COPIES CPSRC TO CPDEST BOTH PASSED BY NAME + ; KILLS CPDEST FIRST + N CPINSTR + I DEBUG W "MADE IT TO COPY",CPSRC,CPDEST,! + I @CPSRC@(0)<1 D ; BAD LENGTH + . W "ERROR IN COPY BAD SOURCE LENGTH: ",CPSRC,! + . Q + ; I '$D(@CPDEST@(0)) S @CPDEST@(0)=0 ; IF THE DEST IS EMPTY, INITIALIZE + D QUEUE("CPINSTR",CPSRC,1,@CPSRC@(0)) ; BLIST FOR ENTIRE ARRAY + D BUILD("CPINSTR",CPDEST) + Q + ; +QOPEN(QOBLIST,QOXML,QOXPATH) ; ADD ALL BUT THE LAST LINE OF QOXML TO QOBLIST + ; WARNING NEED TO DO QCLOSE FOR SAME XML BEFORE CALLING BUILD + ; QOXPATH IS OPTIONAL - IF PROVIDED, WILL OPEN INSIDE THE XPATH POINT + ; USED TO INSERT CHILDREN NODES + I @QOXML@(0)<1 D ; MALFORMED XML + . W "MALFORMED XML PASSED TO QOPEN: ",QOXML,! + . Q + I DEBUG W "DOING QOPEN",! + N S1,E1,QOT,QOTMP + S S1=1 ; OPEN FROM THE BEGINNING OF THE XML + I $D(QOXPATH) D ; XPATH PROVIDED + . D QUERY(QOXML,QOXPATH,"QOT") ; INSURE INDEX + . S E1=$P(@QOXML@(QOXPATH),"^",2)-1 + I '$D(QOXPATH) D ; NO XPATH PROVIDED, OPEN AT ROOT + . S E1=@QOXML@(0)-1 + D QUEUE(QOBLIST,QOXML,S1,E1) + ; S QOTMP=QOXML_"^"_S1_"^"_E1 + ; D PUSH(QOBLIST,QOTMP) + Q + ; +QCLOSE(QCBLIST,QCXML,QCXPATH) ; CLOSE XML AFTER A QOPEN + ; ADDS THE LIST LINE OF QCXML TO QCBLIST + ; USED TO FINISH INSERTING CHILDERN NODES + ; QCXPATH IS OPTIONAL - IF PROVIDED, WILL CLOSE UNTIL THE END + ; IF QOPEN WAS CALLED WITH XPATH, QCLOSE SHOULD BE TOO + I @QCXML@(0)<1 D ; MALFORMED XML + . W "MALFORMED XML PASSED TO QCLOSE: ",QCXML,! + I DEBUG W "GOING TO CLOSE",! + N S1,E1,QCT,QCTMP + S E1=@QCXML@(0) ; CLOSE UNTIL THE END OF THE XML + I $D(QCXPATH) D ; XPATH PROVIDED + . D QUERY(QCXML,QCXPATH,"QCT") ; INSURE INDEX + . S S1=$P(@QCXML@(QCXPATH),"^",2) ; REMAINING XML + I '$D(QCXPATH) D ; NO XPATH PROVIDED, CLOSE AT ROOT + . S S1=@QCXML@(0) + D QUEUE(QCBLIST,QCXML,S1,E1) + ; D PUSH(QCBLIST,QCXML_";"_S1_";"_E1) + Q + ; +INSERT(INSXML,INSNEW,INSXPATH) ; INSERT INSNEW INTO INSXML AT THE + ; INSXPATH XPATH POINT INSXPATH IS OPTIONAL - IF IT IS + ; OMITTED, INSERTION WILL BE AT THE ROOT + ; NOTE INSERT IS NON DESTRUCTIVE AND WILL ADD THE NEW + ; XML AT THE END OF THE XPATH POINT + ; INSXML AND INSNEW ARE PASSED BY NAME INSXPATH IS A VALUE + N INSBLD,INSTMP + I DEBUG W "DOING INSERT ",INSXML,INSNEW,INSXPATH,! + I DEBUG F G1=1:1:@INSXML@(0) W @INSXML@(G1),! + I '$D(@INSXML@(0)) D Q ; INSERT INTO AN EMPTY ARRAY + . D CP^GPLXPATH(INSNEW,INSXML) ; JUST COPY INTO THE OUTPUT + I $D(@INSXML@(0)) D ; IF ORIGINAL ARRAY IS NOT EMPTY + . I $D(INSXPATH) D ; XPATH PROVIDED + . . D QOPEN("INSBLD",INSXML,INSXPATH) ; COPY THE BEFORE + . . I DEBUG ZWR INSBLD + . I '$D(INSXPATH) D ; NO XPATH PROVIDED, OPEN AT ROOT + . . D QOPEN("INSBLD",INSXML,"//") ; OPEN WITH ROOT XPATH + . D QUEUE("INSBLD",INSNEW,1,@INSNEW@(0)) ; COPY IN NEW XML + . I $D(INSXPATH) D ; XPATH PROVIDED + . . D QCLOSE("INSBLD",INSXML,INSXPATH) ; CLOSE WITH XPATH + . I '$D(INSXPATH) D ; NO XPATH PROVIDED, CLOSE AT ROOT + . . D QCLOSE("INSBLD",INSXML,"//") ; CLOSE WITH ROOT XPATH + . D BUILD("INSBLD","INSTMP") ; PUT RESULTS IN INDEST + . D CP^GPLXPATH("INSTMP",INSXML) ; COPY BUFFER TO SOURCE + Q + ; +INSINNER(INNXML,INNNEW,INNXPATH) ; INSERT THE INNER XML OF INNNEW + ; INTO INNXML AT THE INNXPATH XPATH POINT + ; + N INNBLD,UXPATH + N INNTBUF + S INNTBUF=$NA(^TMP($J,"INNTBUF")) + I '$D(INNXPATH) D ; XPATH NOT PASSED + . S UXPATH="//" ; USE ROOT XPATH + I $D(INNXPATH) S UXPATH=INNXPATH ; USE THE XPATH THAT'S PASSED + I '$D(@INNXML@(0)) D ; INNXML IS EMPTY + . D QUEUE^GPLXPATH("INNBLD",INNNEW,2,@INNNEW@(0)-1) ; JUST INNER XML + . D BUILD("INNBLD",INNXML) + I @INNXML@(0)>0 D ; NOT EMPTY + . D QOPEN("INNBLD",INNXML,UXPATH) ; + . D QUEUE("INNBLD",INNNEW,2,@INNNEW@(0)-1) ; JUST INNER XML + . D QCLOSE("INNBLD",INNXML,UXPATH) + . D BUILD("INNBLD",INNTBUF) ; BUILD TO BUFFER + . D CP(INNTBUF,INNXML) ; COPY BUFFER TO DEST + Q + ; +REPLACE(REXML,RENEW,REXPATH) ; REPLACE THE XML AT THE XPATH POINT + ; WITH RENEW - NOTE THIS WILL DELETE WHAT WAS THERE BEFORE + ; REXML AND RENEW ARE PASSED BY NAME XPATH IS A VALUE + ; THE DELETED XML IS PUT IN ^TMP($J,"REPLACE_OLD") + N REBLD,XFIRST,XLAST,OLD,XNODE,RETMP + S OLD=$NA(^TMP($J,"REPLACE_OLD")) + D QUERY(REXML,REXPATH,OLD) ; CREATE INDEX, TEST XPATH, MAKE OLD + S XNODE=@REXML@(REXPATH) ; PULL OUT FIRST AND LAST LINE PTRS + S XFIRST=$P(XNODE,"^",1) + S XLAST=$P(XNODE,"^",2) + D QUEUE("REBLD",REXML,1,XFIRST) ; THE BEFORE + I RENEW'="" D ; NEW XML IS NOT NULL + . D QUEUE("REBLD",RENEW,1,@RENEW@(0)) ; THE NEW + D QUEUE("REBLD",REXML,XLAST,@REXML@(0)) ; THE REST + I DEBUG W "REPALCE PREBUILD",! + I DEBUG ZWR REBLD + D BUILD("REBLD","RTMP") + K @REXML ; KILL WHAT WAS THERE + D CP("RTMP",REXML) ; COPY IN THE RESULT + Q + ; +MISSING(IXML,OARY) ; SEARTH THROUGH INXLM AND PUT ANY @@X@@ VARS IN OARY + ; W "Reporting on the missing",! + ; W OARY + I '$D(@IXML@(0)) W "MALFORMED XML PASSED TO MISSING",! Q + N I + S @OARY@(0)=0 ; INITIALIZED MISSING COUNT + F I=1:1:@IXML@(0) D ; LOOP THROUGH WHOLE ARRAY + . I @IXML@(I)?.E1"@@".E D ; MISSING VARIABLE HERE + . . D PUSH^GPLXPATH(OARY,$P(@IXML@(I),"@@",2)) ; ADD TO OUTARY + . . Q + Q + ; +MAP(IXML,INARY,OXML) ; SUBSTITUTE @@X@@ VARS IN IXML WITH VALUES IN INARY + ; AND PUT THE RESULTS IN OXML + I '$D(@IXML@(0)) W "MALFORMED XML PASSED TO MAP",! Q + I $O(@INARY@(""))="" W "EMPTY ARRAY PASSED TO MAP",! Q + N I,TNAM,TVAL + S @OXML@(0)=@IXML@(0) ; TOTAL LINES IN OUTPUT + F I=1:1:@OXML@(0) D ; LOOP THROUGH WHOLE ARRAY + . S @OXML@(I)=@IXML@(I) ; COPY THE LINE TO OUTPUT + . I @OXML@(I)?.E1"@@".E D ; IS THERE A VARIABLE HERE? + . . S TNAM=$P(@OXML@(I),"@@",2) ; EXTRACT THE VARIABLE NAME + . . I $D(@INARY@(TNAM)) D ; IS THE VARIABLE IN THE MAP? + . . . S TVAL=@INARY@(TNAM) ; PULL OUT MAPPED VALUE + . . . S @OXML@(I)=$P(@OXML@(I),"@@",1)_TVAL_$P(@OXML@(I),"@@",3) ;MAPIT + W "MAPPED",! + Q + ; +PARY(GLO) ;PRINT AN ARRAY + N I + F I=1:1:@GLO@(0) W @GLO@(I),! + Q + ; +TEST ; Run all the test cases + D TESTALL^GPLUNIT("GPLXPATH") + Q + ; +OLDTEST ; RUN ALL THE TEST CASES + N ZTMP + D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") + D ZTEST^GPLUNIT(.ZTMP,"ALL") + W "PASSED: ",TPASSED,! + W "FAILED: ",TFAILED,! + W ! + ; W "THE TESTS!",! + ; ZWR ZTMP + Q + ; +ZTEST(WHICH) ; RUN ONE SET OF TESTS + N ZTMP + S DEBUG=1 + D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") + D ZTEST^GPLUNIT(.ZTMP,WHICH) + Q + ; +TLIST ; LIST THE TESTS + N ZTMP + D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") + D TLIST^GPLUNIT(.ZTMP) + Q + ; +;;> +;;> +;;>>>K GPL S GPL="" +;;>>>D PUSH^GPLXPATH("GPL","FIRST") +;;>>>D PUSH^GPLXPATH("GPL","SECOND") +;;>>>D PUSH^GPLXPATH("GPL","THIRD") +;;>>>D PUSH^GPLXPATH("GPL","FOURTH") +;;>>?GPL(0)=4 +;;> +;;>>>K GXML S GXML="" +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","@@DATA1@@") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","@@DATA2@@") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;> +;;>>>K GXML S GXML="" +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","DATA1") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","DATA2") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","<_SECOND>") +;;>>>D PUSH^GPLXPATH("GXML","DATA3") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;>>>D PUSH^GPLXPATH("GXML","") +;;> +;;>>>D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") +;;>>>D ZTEST^GPLUNIT(.ZTMP,"INIT") +;;>>?GPL(GPL(0))="FOURTH" +;;>>>D POP^GPLXPATH("GPL",.GX) +;;>>?GX="FOURTH" +;;>>?GPL(GPL(0))="THIRD" +;;>>>D POP^GPLXPATH("GPL",.GX) +;;>>?GX="THIRD" +;;>>?GPL(GPL(0))="SECOND" +;;> +;;>>>D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") +;;>>>D ZTEST^GPLUNIT(.ZTMP,"INIT") +;;>>>S GX="" +;;>>>D MKMDX^GPLXPATH("GPL",.GX) +;;>>?GX="//FIRST/SECOND/THIRD/FOURTH" +;;> +;;>>?$$XNAME^GPLXPATH("DATA1")="FOURTH" +;;>>?$$XNAME^GPLXPATH("")="SIXTH" +;;>>?$$XNAME^GPLXPATH("")="THIRD" +;;> +;;>>>D ZLOAD^GPLUNIT("ZTMP","GPLXPATH") +;;>>>D ZTEST^GPLUNIT(.ZTMP,"INITXML") +;;>>>D INDEX^GPLXPATH("GXML") +;;>>?GXML("//FIRST/SECOND")="2^12" +;;>>?GXML("//FIRST/SECOND/THIRD")="3^9" +;;>>?GXML("//FIRST/SECOND/THIRD/FIFTH")="5^7" +;;>>?GXML("//FIRST/SECOND/THIRD/FOURTH")="4^4" +;;>>?GXML("//FIRST/SECOND/THIRD/SIXTH")="8^8" +;;>>?GXML("//FIRST/SECOND")="2^12" +;;>>?GXML("//FIRST")="1^13" +;;> +;;>>>D ZTEST^GPLXPATH("INITXML2") +;;>>>D INDEX^GPLXPATH("GXML") +;;>>?GXML("//FIRST/SECOND")="2^12" +;;>>?GXML("//FIRST/SECOND/_SECOND")="9^11" +;;>>?GXML("//FIRST/SECOND/_SECOND/FOURTH")="10^10" +;;>>?GXML("//FIRST/SECOND/THIRD")="3^8" +;;>>?GXML("//FIRST/SECOND/THIRD/FOURTH")="4^7" +;;>>?GXML("//FIRST")="1^13" +;;> +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>S OUTARY="^TMP($J,""MISSINGTEST"")" +;;>>>D MISSING^GPLXPATH("GXML",OUTARY) +;;>>?@OUTARY@(1)="DATA1" +;;>>?@OUTARY@(2)="DATA2" +;;> +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>S MAPARY="^TMP($J,""MAPVALUES"")" +;;>>>S OUTARY="^TMP($J,""MAPTEST"")" +;;>>>S @MAPARY@("DATA2")="VALUE2" +;;>>>D MAP^GPLXPATH("GXML",MAPARY,OUTARY) +;;>>?@OUTARY@(6)="VALUE2" +;;> +;;>>>D QUEUE^GPLXPATH("BTLIST","GXML",2,3) +;;>>>D QUEUE^GPLXPATH("BTLIST","GXML",4,5) +;;>>?$P(BTLIST(2),";",2)=4 +;;> +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD/FOURTH","G2") +;;>>>D ZTEST^GPLXPATH("QUEUE") +;;>>>D BUILD^GPLXPATH("BTLIST","G3") +;;> +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D CP^GPLXPATH("GXML","G2") +;;>>?G2(0)=13 +;;> +;;>>>K G2,GBL +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QOPEN^GPLXPATH("GBL","GXML") +;;>>?$P(GBL(1),";",3)=12 +;;>>>D BUILD^GPLXPATH("GBL","G2") +;;>>?G2(G2(0))="" +;;> +;;>>>K G2,GBL +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QOPEN^GPLXPATH("GBL","GXML","//FIRST/SECOND") +;;>>?$P(GBL(1),";",3)=11 +;;>>>D BUILD^GPLXPATH("GBL","G2") +;;>>?G2(G2(0))="" +;;> +;;>>>K G2,GBL +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QCLOSE^GPLXPATH("GBL","GXML") +;;>>?$P(GBL(1),";",3)=13 +;;>>>D BUILD^GPLXPATH("GBL","G2") +;;>>?G2(G2(0))="" +;;> +;;>>>K G2,GBL +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QCLOSE^GPLXPATH("GBL","GXML","//FIRST/SECOND/THIRD") +;;>>?$P(GBL(1),";",3)=13 +;;>>>D BUILD^GPLXPATH("GBL","G2") +;;>>?G2(G2(0))="" +;;>>?G2(1)="" +;;> +;;>>>K G2,GBL,G3,G4 +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD/FIFTH","G2") +;;>>>D INSERT^GPLXPATH("GXML","G2","//FIRST/SECOND/THIRD") +;;>>>D INSERT^GPLXPATH("G3","G2","//") +;;>>?G2(1)=GXML(9) +;;> +;;>>>K G2,GBL,G3 +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD/FIFTH","G2") +;;>>>D REPLACE^GPLXPATH("GXML","G2","//FIRST/SECOND") +;;>>?GXML(3)="" +;;> +;;>>>K GXML,G2,GBL,G3 +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD","G2") +;;>>>D INSINNER^GPLXPATH("GXML","G2","//FIRST/SECOND/THIRD") +;;>>?GXML(10)="" +;;> +;;>>>K GXML,G2,GBL,G3 +;;>>>D ZTEST^GPLXPATH("INITXML") +;;>>>D QUERY^GPLXPATH("GXML","//FIRST/SECOND/THIRD","G2") +;;>>>D INSINNER^GPLXPATH("G2","G2") +;;>>?G2(8)="" +;;>