Sample Call To Approver PKG List
This section provides an example of how to call the APPROVER PKG LIST service from an assembler program.
Setting SERXMLAC Parameter List Values
In this example, we allocate 4K bytes for the request buffer and 32K bytes for the replies.
...
**********************************************************************
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
*
* Allocate storage areas for XML request and reply (SERXMLAC)
*
* IXP$PARM +0 = length of request area
* IXP$PARM +4 = address of request area
* IXP$PARM +8 = length of reply area
* IXP$PARM +12 = address of reply area
* IXP$PARM +16 = address of current '<result>'
* IXP$PARM +20 = total getmain'd storage
*
**********************************************************************
XC IXP$PARM,IXP$PARM clear parmlist
LA R2,4+32 36k request
SLL R2,10 bits
STORAGE OBTAIN,LENGTH=(2), get storage
COND=NO,SP=3, subpool 3
LOC=(ANY,ANY) above, backed anywhere
ST R1,IXP$PARM+4 adr of request area
ST R2,IXP$PARM+20 total getmained length
LA R2,X09@RQLN actual request length
ST R2,IXP$PARM length of request area
LA R2,4 4k request
SLL R2,10 bits
AR R1,R2 bump +4k
LA R2,32 32k reply length
SLL R2,10 bits
ST R2,IXP$PARM+8 length of reply area
ST R1,IXP$PARM+12 adr of reply area
ST R1,IXP$PARM+16 save current result pointer
...
Building the XML Services Request Buffer
In this example, we are calling the APPROVER PKG LIST service. The request must include the package name and subsystem ID at tags <package> and <subsys> respectively.
XML Request Area
The following code shows the request area for the APPROVER PKG LIST request.
...
**********************************************************************
*
* XML Request
*
**********************************************************************
X09@XMLR DS 0H XML request block
DC C'<?xml version="1.0"?>'
DC C'<service name="APPROVER">'
DC C' <scope name="PKG">'
DC C' <message name="LIST">'
DC C' <header>'
DC C' <subsys>'
X09@SUBS EQU *-X09@XMLR,1
DC C'x'
DC C'</subsys>'
DC C' <test>T</test>'
DC C' <product>CMN</product>'
DC C' </header>'
DC C' <request>'
DC C' <package>'
X09@PKGN EQU *-X09@XMLR,10
DC C'aaaannnnnn'
DC C'</package>'
DC C' </request>'
DC C' </message>'
DC C' </scope>'
DC C' </service>'
X09@RQLN EQU *-X09@XMLR request length
...
Setting Request Tag Values
To make the program reentrant and reusable, move the request block to allocated storage, and then move data values to fields imbedded in the appropriate tag names.
In this example, the subsystem ID comes from X09@SUBS and the package name comes from X09@PKGN.
...
**********************************************************************
*
* Move request to SERXMLAC request buffer
*
**********************************************************************
L R0,IXP$PARM+4 target request area
L R1,IXP$PARM target request length
LA R14,X09@XMLR source tags
LR R15,R1 ditto request length
MVCL R0,R14 source request to area
**********************************************************************
*
* Move service filtering data to SERXMLAC request buffer
*
**********************************************************************
L R1,IXP$PARM+4 restore request area
MVC X09@SUBS(,R1),IXP$SUBS ZMF subsys id
MVC X09@PKGN(,R1),IXP$PNAM package name
...
Calling SERXMLAC
After the request buffer has been populated, the address of the parameter list is passed in register 1, per normal convention, and SERXMLAC is called.
**********************************************************************
*
* Call SERXMLAC with service request.
*
**********************************************************************
LA R1,IXP$PARM parameter list for serxmlac
ST R1,IXP$WORK store parmlist address
LOAD EP=SERXMLAC
LR R15,R0 epa
LA R1,IXP$WORK
BASSM R14,R15 call it
LTR R15,R15 okay?
BNZ X09$9000 .no, error
...
Processing the Reply Buffer
All replies are returned from the call in a single burst. The caller is responsible for ensuring that the amount of storage allocated for the reply buffer is large enough to hold as many results as are expected or required.
Reply data is wrapped in XML tags, starting with the usual header tags (XML version, service, scope, and message), one or more sets of results tags, followed by the response tags (return message, return code, and reason code).
When you process replies, scan the reply buffer for the tags you are interested in, and examine the enclosed data. The buffer may contain multiple sets of result tags, so scan for the <result> tag first, which indicates the beginning of one result. Each result is terminated by a ending tag. The <response> tag indicates the end of all results.
GETTAG Subroutine
This is the code for the GETTAG subroutine that parses the reply buffer to extract package approver information returned by XML Services.
...
**********************************************************************
* GETTAG - find tag at R1
*
*Input R0 = length of tag value
* R1 = adr of tag value
* XML$PARM+16 start of search area
*
*Output R0 = length of data value
* R1 = adr of data value
* R15= +0 tag and data found
* R15= +4 tag not found before </result>
* R15= +8 tag not found before </response>
*********************************************************************
GETTAG DS 0H
BAKR R14,0 stack registers
LR R14,R1 save tag value adr
LR R3,R0 save tag value length
BCTR R3,0 -1 for ex instr
L R4,XML$PARM+16 start of search
GETT0100 DS 0H
TRT 0(256,R4),TRTBL look for chevron
BZ GETT9100 not found - end of data
CLC 0(9,R4),=C'</result>' end of result?
BE GETT9000 .yes, end of this result
CLC 0(11,R4),=C'</response>' end of response?
BE GETT9100 .yes, end of data
EX R3,GETTCMPR compare tag with request
LA R4,1(,R4) bump past chevron
BNE GETT0100 not found, keep looking
LA R4,0(R3,R4) bump over tag
LR R5,R4 save start of reply data
TRT 0(256,R4),TRTBL look for next chevron
BZ GETT9100 not found - some error
SR R1,R5 R1 = length of data
LR R0,R1 R0 = length of data
LR R1,R4 R1 = adr of data
XR R15,R15 good return code
B GETT9900 return
GETT9000 DS 0H
LR R1,R4 adr of </result>
LA R15,4 </result> found before tag
B GETT9900 return
GETT9100 DS 0H
LR R1,R4 adr of </response>
LA R15,8 </response> found before tag
* B GETT9900 return
GETT9900 DS 0H
PR , unstack, return
**********************************************************************
* DATA AREAS
**********************************************************************
GETTCMPR CLC 0(*-*,R4),0(R14) matching tag name?
LTORG
**********************************************************************
* Translate table for '<'
**********************************************************************
TRTBL DC 256AL1(0)
ORG TRTBL+C'<'
DC C'<'
ORG
GETTAG Subroutine Processing
This sample GETTTAG subroutine scans the reply buffer searching for a tag pointed to by register 1. If a tag is discovered before the required tag name is found, the return code is set to +4, indicating the end of the current reply. If a tag is discovered before the required tag name is found, the return code is set to +8, indicating that all results have been exhausted.
The sequence of events for managing reply tags should be:
-
Point Register 1 (R1) at the start of the reply buffer.
-
Scan for the first <result> tag.
-
Set R1 (stored in IXP$PARM+16 in this example) to the start of the <result>.
-
Point R1 to a tag name you wish to interrogate.
-
Call the GETTAG routine. If found, the data within the tag will be located at R1, and its length in R0.
-
Continue calling the GETTAG routine with whatever tag names you wish to interrogate.
-
When GETTAG returns RC=4 (end of <result>), point R1 at the next set of <result>s, and go to step 3.
-
When GETTAG returns with RC=8 (end of <response>), all results have been processed.