Skip to content

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:

  1. Point Register 1 (R1) at the start of the reply buffer.

  2. Scan for the first <result> tag.

  3. Set R1 (stored in IXP$PARM+16 in this example) to the start of the <result>.

  4. Point R1 to a tag name you wish to interrogate.

  5. Call the GETTAG routine. If found, the data within the tag will be located at R1, and its length in R0.

  6. Continue calling the GETTAG routine with whatever tag names you wish to interrogate.

  7. When GETTAG returns RC=4 (end of <result>), point R1 at the next set of <result>s, and go to step 3.

  8. When GETTAG returns with RC=8 (end of <response>), all results have been processed.