ABS383E       ; Do the sort and generate the XML Response to a database query [ 12/06/1999  12:01 AM ]

            ; For CECS 383: The Science and Technology of the World Wide Web by Arthur B. Smith (754104)

       

Sort(Tree)       ; Sort the results in @Tree based on the sort parameters (also in @Tree) if any

            ; Search for the Sort parameters, if any

        New NodeNo,Tag,Sorted,SortNode,Field,Dir,Step,Task

        Set U="^"

        Set Sorted=0

        Set NodeNo=4

        Set NodeNo=$Order(@Tree@(1,"Query",NodeNo))

        If NodeNo Do

        . Set Tag=$Order(@Tree@(1,"Query",NodeNo,""))

        . If Tag="Sort" Set Sorted=1

        If Sorted Do

        . Set Root="@Tree@(1,""Query"",NodeNo,""Sort"",""MATCH"""

        . Set Task(0.1)="SET Node=Root"

        . Set SortNode=""

        . For Step=1:1  Set SortNode=$Order(@Tree@(1,"Query",NodeNo,"Sort",SortNode)) Quit:SortNode=""  Quit:SortNode="DIR"  Do

        . . Set Field=@Tree@(1,"Query",NodeNo,"Sort",SortNode,"Field")

        . . Set SortNode=SortNode+2

        . . Set $Piece(@Tree@(1,"Query",NodeNo,"Sort","DIR"),U,Step)=$Select($Order(@Tree@(1,"Query",NodeNo,"Sort",SortNode,""))="DOWN":1,1:-1)

        . . Set Task(Step)="SET Val=$$GET1^DIQ(FileNo,IEN_"","","_Field_")"

        . . Set Task(Step+.1)="SET Node=Node_"",""""""_Val_"""""""""

        . Set Task(Step+1)="Set Node=Node_"",""_IEN_"")"""

        . Set Task(Step+2)="SET @Node="""""

        . Set IEN=0

        . For  Set IEN=$Order(@Tree@(1,"Query",4,"Select","MATCH",IEN))  Quit:IEN=""  Do 

        . . Set Step=0

        . . For  Set Step=$Order(Task(Step)) Quit:Step=""  Do

        . . . Xecute Task(Step)

        Else  Do

            . ; No sort parameters, so just copy the results of the selection.

        . Set NodeNo=SelNode+0.5  ; Create a false Sort Node

        . Merge @Tree@(1,"Query",NodeNo,"Sort","MATCH")=@Tree(1,"Query",4,"Select","MATCH")

        . Set @Tree@(1,"Quey",NodeNo,"Sort","DIR")=""

        Quit

       

GenResp(Tree)           ; Generate the XML response from the search results in @Tree

        New FNLen,DTDName,NodeNo

        Set FNLen=$Length(FName,"\")  ; Number of subdirectories in file name

            ; Generate a response DTD for this file in the same directory as the query, called R<fileno>.DTD

        Set DTDName=$Piece(FName,"\",1,FNLen-1)_"\R"_FileNo_".DTD"

        Do GenRDTD^ABS383B(FileNo,DTDName)

            ; Determine if there is a projection specified in the query

        Set NodeNo=4,Projected=0

        For  Set NodeNo=$Order(@Tree@(1,"Query",NodeNo)) Quit:NodeNo=""  Do  Quit:Projected

        . If NodeNo Do

        . . Set Tag=$Order(@Tree@(1,"Query",NodeNo,""))

        . . If Tag="Project" Set Projected=1

            ; Save the response in the same file name as the query with an "R" prepended to the name

        Set OFName=$Piece(FName,"\",1,FNLen-1)_"\R"_$Piece(FName,"\",FNLen)

        Open 51:(OFName:"W")

        Use 51

        Write "<?xml version=""1.0""?>",!

        Write "<!DOCTYPE Response SYSTEM """_DTDName_""">",!

        Write "<!-- Response to query ",FName," -->",!

        Write "<Response>",!

        Set SNodeNo=$Order(@Tree@(1,"Query",4)) ; This should be the SORT node

        Set PNodeNo=$Order(@Tree@(1,"Query",SNodeNo)) ; This should be the Project node, if there is one

        Set MNode(0)=$Name(@Tree@(1,"Query",SNodeNo,"Sort","MATCH"))

        Set Task=""

        For Piece=1:1 Set Dir=$Piece(@Tree@(1,"Query",SNodeNo,"Sort","DIR"),U,Piece) Quit:Dir=""  Do

        . Set Task=Task_"SET S("_Piece_")="""" FOR  SET S("_Piece_")=$ORDER(@MNode("_(Piece-1)_")@(S("_Piece_")),"_Dir_") QUIT:S("_Piece_")=""""  SET MNode("_Piece_")=$NAME(@MNode("_(Piece-1)_")@(S("_Piece_"))) "

        Set Task=Task_"SET S("_Piece_")="""" FOR  SET S("_Piece_")=$ORDER(@MNode("_(Piece-1)_")@(S("_Piece_"))) QUIT:S("_Piece_")=""""  "

        Set Task=Task_"DO Output(S("_Piece_")) "

        Xecute Task

        Write "</Response>",!

        Close 51

        Quit

       

Output(IEN)    ; Generate the projected output for IEN

            ; Determine if there is a Project tag

        Set U="^"

        Set IENS=IEN_","

        Write "  <",$Order(@Tree@(1,"Query",2,"File",3,""))," IENS=""",IENS,""">",!

        If Projected Do

        . Set Fields=@Tree@(1,"Query",NodeNo,"Project")

        . Do GETS^DIQ(FileNo,IENS,Fields,"N",$Name(@Tree@(1,"Query",NodeNo,"Project","MATCH")))

        Else  Do

        . Set NodeNo=9999  ; Make a safe one up!

            . ; No Project, so output ALL fields for this record

        . Do GETS^DIQ(FileNo,IENS,"*","N",$Name(@Tree@(1,"Query",NodeNo,"Project","MATCH")))

            ;Resulsts are now in @Tree@(1,"Query",NodeNo,"Project","MATCH",FileNo,IENS,FieldNo)=Value

        Set FieldNo=""

        For  Set FieldNo=$Order(@Tree@(1,"Query",NodeNo,"Project","MATCH",FileNo,IENS,FieldNo)) Quit:FieldNo=""  Do

        . If '$Data(FldName(FieldNo)) Set FldName(FieldNo)="B-"_FileNo_"z"_FieldNo_"-"_$Translate($Piece($Get(^DD(FileNo,FieldNo,0)),U,1)," ","_")

        . Write "    <",FldName(FieldNo),">"

            . ; Watch for special characters....

        . Set CPDATA=@Tree@(1,"Query",NodeNo,"Project","MATCH",FileNo,IENS,FieldNo)

        . Set Offs=1

        . For  Set Offs=$Find(CPDATA,"&",Offs) Quit:Offs=0  Do

        . . Set CPDATA=$Extract(CPDATA,1,Offs-2)_"&amp;"_$Extract(CPDATA,Offs,$Length(CPDATA))

        . Set Offs=1

        . For  Set Offs=$Find(CPDATA,"<",Offs) Quit:Offs=0  Do

        . . Set CPDATA=$Extract(CPDATA,1,Offs-2)_"&lt;"_$Extract(CPDATA,Offs,$Length(CPDATA))

        . Set Offs=1

        . For  Set Offs=$Find(CPDATA,"'",Offs) Quit:Offs=0  Do

        . . Set CPDATA=$Extract(CPDATA,1,Offs-2)_"&apos;"_$Extract(CPDATA,Offs,$Length(CPDATA))

        . Set Offs=1

        . For  Set Offs=$Find(CPDATA,"""",Offs) Quit:Offs=0  Do

        . . Set CPDATA=$Extract(CPDATA,1,Offs-2)_"&quot;"_$Extract(CPDATA,Offs,$Length(CPDATA))

        . Write CPDATA

        . Write