XMLSERVICERPG Toolkit

(click to open)

Quick Page Table of Contents

Scanning…

RPG Toolkit For XMLSERVICE …

Goto Main Page
Goto Documents

This is a sample version RPG toolkit used for Gateway400 demo, it was built in 2 days (and it works), but …

Still under construction, APIs may change (break you application)

  • working on high speed persistent DB2 connection (xml_Auth_t)
  • working on concept of requiring unique name input (XML_UNAME_NOT_UNIQUE)
  • working on full API param documentation in header file (rpgkit_h)
  • missing binary type for XMLSERVICE calls (working)

download xmlservice 1.8.2+ (main page)

RPG Toolkit (RPGKIT srvpgm) demonstrates techniques to help RPGers deal with XML parsing used in XMLSERVICE calls.

  • RPGKIT is a 100% pure RPG solution, therefore you do NOT need PHP or any other scripting language installed on your machine, only download xmlservice 1.8.2+.
    • License same BSD included with xmlservice 1.8.2+ download (please have at it, here to help fellow RPGers)
  • IBM i machines ALL support DRDA (WRKRDBDIRE), therefore RPGKIT is using DB2 for local/remote transport between your RPG code and XMLSERVICE (IBM i cool).
    • Maybe RPGKIT will add a HTTP (REST) transport, but with fantastic DRDA local/remote DB2 on machines “for free” seems waste of time to Apache everything.
  • RPGKIT should make conversions between XML (string) and RPG values like packed decimal, zoned decimal, etc., much easier (see zzrpgkit sample below).
    rc = getVal(xml:'DSDEC2':%addr(DEC12p2));
    

It is a work in progress, so you probably should not use for production until it ages a bit with feedback.

installation

First, add XMLSERVICE to library list: 
> ADDLIBLE XMLSERVICE

Follow directions for xmlservice install (main page).
> CRTCLPGM PGM(XMLSERVICE/CRTXML) SRCFILE(XMLSERVICE/QCLSRC)
> call crtxml

You should also create the test cases used in sample (main page).
> CRTCLPGM PGM(XMLSERVICE/CRTTEST) SRCFILE(XMLSERVICE/QCLSRC)
> call crttest

Create toolkit (RPGKIT.SRVPGM) and sample (ZZRPGKIT.PGM ZZMYAUTH.SRVPGM):
> CRTCLPGM PGM(XMLSERVICE/CRTKIT) SRCFILE(XMLSERVICE/QCLSRC)
> call crtkit

Use your favorite debugger to run ZZRPGKIT and see how it all works (demo Gateway400)

Interface (rpgkit_h)

      /if defined(RPGKIT_H)
      /eof
      /endif
      /define RPGKIT_H

      *****************************************************
      * Copyright (c) 2010, IBM Corporation
      * All rights reserved.
      *
      * Redistribution and use in source and binary forms, 
      * with or without modification, are permitted provided 
      * that the following conditions are met:
      * - Redistributions of source code must retain 
      *   the above copyright notice, this list of conditions 
      *   and the following disclaimer. 
      * - Redistributions in binary form must reproduce the 
      *   above copyright notice, this list of conditions 
      *   and the following disclaimer in the documentation 
      *   and/or other materials provided with the distribution.
      * - Neither the name of the IBM Corporation nor the names 
      *   of its contributors may be used to endorse or promote 
      *   products derived from this software without specific 
      *   prior written permission. 
      *
      * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
      * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
      * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
      * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
      * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
      * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
      * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
      * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
      * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
      * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
      * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
      * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
      * POSSIBILITY OF SUCH DAMAGE.
      *****************************************************

      *****************************************************
      * xmlservice template (see crtXML, callXML, dltXML)
      *****************************************************
     D xml_Auth_t      ds                  qualified based(Template)
     D  xml_db                       10A
     D  xml_uid                      10A
     D  xml_pwd                      10A

     D xml_Rec_t       ds                  qualified based(Template)
     D  xml_auth                           likeds(xml_Auth_t)
     D  xml_ipc                    1024A
     D  xml_ctl                    1024A
     D  xml_in_sz                    10i 0
     D  xml_in_len                   10i 0
     D  xml_out_sz                   10i 0
     D  xml_out_len                  10i 0
     D  xml_in_p                       *
     D  xml_out_p                      *

      *****************************************************
      * xmlservice const (note _C are for internal use only)
      *****************************************************

     D XML_4K          c                   const(4096)
     D XML_32K         c                   const(32768)
     D XML_65K         c                   const(65536)
     D XML_512K        c                   const(524288)
     D XML_1M          c                   const(1048576)
     D XML_5M          c                   const(5242880)
     D XML_10M         c                   const(10485760)
     D XML_15M         c                   const(15728640)

     D XML_SUCCESS     c                   const(0)
     D XML_FAILURE     c                   const(-1)
     D XML_UNAME_NOT_UNIQUE...
     D                 c                   const(-2)

     D XML_IO_IN       c                   const(1)
     D XML_IO_IN_C...
     D                 c                   const('io="in"')
     D XML_IO_OUT      c                   const(2)
     D XML_IO_OUT_C...
     D                 c                   const('io="out"')
     D XML_IO_BOTH     c                   const(3)
     D XML_IO_BOTH_C...
     D                 c                   const('io="both"')

     D XML_CMD_EXC     c                   const(1)
     D XML_CMD_EXC_C...
     D                 c                   const('exec="cmd"')
     D XML_CMD_SYS     c                   const(2)
     D XML_CMD_SYS_C...
     D                 c                   const('exec="system"')
     D XML_CMD_REX     c                   const(3)
     D XML_CMD_REX_C...
     D                 c                   const('exec="rexx"')

     D XML_ROW_ON      c                   const(1)
     D XML_ROW_ON_C...
     D                 c                   const('row="on"')
     D XML_ROW_OFF     c                   const(2)
     D XML_ROW_OFF_C...
     D                 c                   const('')


     D XML_OPM_ON      c                   const(1)
     D XML_OPM_ON_C...
     D                 c                   const('mode="on"')
     D XML_OPM_OFF     c                   const(2)
     D XML_OPM_OFF_C...
     D                 c                   const('')

     D XML_ERR_ON      c                   const(1)
     D XML_ERR_ON_C...
     D                 c                   const('error="on"')
     D XML_ERR_OFF     c                   const(2)
     D XML_ERR_OFF_C...
     D                 c                   const('error="off"')
     D XML_ERR_FAST...
     D                 c                   const(3)
     D XML_ERR_FAST_C...
     D                 c                   const('error="fast"')

      *****************************************************
      * Create XMLSERVICE template.
      *
      * auth.xml_db = '*LOCAL';  // database (WRKRDBDIRE)
      * auth.xml_uid = 'MYPROF'; // connect profile
      * auth.xml_pwd = 'MYPWD';  // connect password
      *
      * xml = crtXML(
      *       auth       // authorization (xml_Auth_t)
      *      :*BLANKS    // ipc route (private connect)
      *      :'*here'    // control (reserved words)
      *      :XML_4K     // size input xml (4k .. 15M)
      *      :XML_15M);  // size output xml (4k .. 15M)
      *****************************************************
     D crtXML          PR                  likeds(xml_Rec_t)
     D  auth                               likeds(xml_Auth_t)
     D  ipc                        1024A   value
     D  ctl                        1024A   value
     D  sz_in                        10i 0 value
     D  sz_out                       10i 0 value

      *****************************************************
      * Execute XMLSERVICE template (call xmlservice).
      *
      * rc = callXML(xml);
      *
      * RETURN
      *   XML_SUCCESS          -- success
      *   XML_FAILURE          -- failure
      *****************************************************
     D callXML         PR            10i 0
     D  xml                                likeds(xml_Rec_t)

      *****************************************************
      * Destroy XMLSERVICE template.
      *
      * dltXML(xml);
      *
      *****************************************************
     D dltXML          PR
     D  xml                                likeds(xml_Rec_t)

      *****************************************************
      * Create XMLSERVICE *CMD template.
      *
      * rc = crtCmd(xml:'chg1':'CHGLIBL LIBL(QTEMP XMLSERVICE)');
      *
      * RETURN
      *   XML_SUCCESS          -- success
      *   XML_FAILURE          -- failure
      *   XML_UNAME_NOT_UNIQUE -- failure, choose new uname
      *****************************************************
     D crtCmd          PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  cmd                        1024a   value
     D  err                          10i 0 value options(*nopass)
     D  exc                          10i 0 value options(*nopass)

      *****************************************************
      * Copy CMD output "as string" returned from XMLSERVICE.
      *
      * rc = crtCmd(xml:'rtv1':'RTVJOBA USRLIBL(?) SYSLIBL(?)');
      *
      * rc = getCmdStr(xml:'USRLIBL':%addr(sULib):%size(sULib));
      *****************************************************
     D getCmdStr       PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  str                            *   value
     D  slen                         10i 0 value
     D  idx                          10i 0 value options(*nopass)

      *****************************************************
      * Create XMLSERVICE PASE utility template.
      *
      * rc = crtSh(xml:'ps1':'ps -ef');
      *
      * RETURN
      *   XML_SUCCESS          -- success
      *   XML_FAILURE          -- failure
      *   XML_UNAME_NOT_UNIQUE -- failure, choose new uname
      *****************************************************
     D crtSH           PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  sh                         1024a   value
     D  row                          10i 0 value options(*nopass)
     D  err                          10i 0 value options(*nopass)

      *****************************************************
      * Copy SH output "as string" returned from XMLSERVICE.
      *
      * rc = crtSH(xml:'wrk1':system -i "WRKSYSVAL OUTPUT(*PRINT)");
      *
      * rc = getSHStr(xml:'wrk1':%addr(sRow):%size(sRow));
      *****************************************************
     D getSHStr        PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  str                            *   value
     D  slen                         10i 0 value
     D  idx                          10i 0 value options(*nopass)

      *****************************************************
      * Create XMLSERVICE *PGM or *SRVPGM template.
      *
      * rc = begPgm(xml:'zz1':'ZZCALL':'XMLSERVICE');
      *  rc = begParm(xml:'p1');
      *   rc = addVal(xml:'v1':'a':10:0:%addr(mychar));
      *  rc = endParm(xml);
      *  rc = begParm(xml:'p2');
      *   rc = begDS(xml:'d1');
      *    rc = addVal(xml:'d1c':'a':10:0:%addr(mychar));
      *    rc = addVal(xml:'d1p':'p':12:2:%addr(mypack));
      *    rc = begDS(xml:'d2':1);
      *     rc = addVal(xml:'d2c':'a':10:0:%addr(mychar));
      *     rc = addVal(xml:'d2s':'s':12:2:%addr(myzone));
      *    rc = endDS(xml);
      *   rc = endDS(xml);
      *  rc = endParm(xml);
      * rc = endPgm(xml);
      *
      * RETURN
      *   XML_SUCCESS          -- success
      *   XML_FAILURE          -- failure
      *   XML_UNAME_NOT_UNIQUE -- failure, choose new uname
      *****************************************************
     D begPgm          PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  name                         10a   value
     D  lib                          10a   value options(*nopass)
     D  func                        128a   value options(*nopass)
     D  opm                          10i 0 value options(*nopass)
     D  err                          10i 0 value options(*nopass)

     D endPgm          PR            10i 0
     D  xml                                likeds(xml_Rec_t)

     D begParm         PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  io                           10i 0 value options(*nopass)

     D endParm         PR            10i 0
     D  xml                                likeds(xml_Rec_t)

     D begDS           PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  dsdim                        10i 0 value options(*nopass)
     D  douname                      10a   value options(*nopass)

     D endDS           PR            10i 0
     D  xml                                likeds(xml_Rec_t)

     D addVal          PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  type                          1a   value
     D  size                         10i 0 value
     D  scale                        10i 0 value
     D  data                           *   value
     D  endname                      10a   value options(*nopass)

      *****************************************************
      * Copy out variable returned from XMLSERVICE.
      *
      * rc = getVal(xml:'DSDEC2':%addr(DEC12p2));
      *****************************************************
     D getVal          PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  data                           *   value
     D  idx                          10i 0 value options(*nopass)


      *****************************************************
      * Copy out variable "as string" returned from XMLSERVICE.
      *
      * rc = getValStr(xml:'INDEC1':%addr(sDEC7p4):%size(sDEC7p4));
      *****************************************************
     D getValStr       PR            10i 0
     D  xml                                likeds(xml_Rec_t)
     D  uname                        10a   value
     D  str                            *   value
     D  slen                         10i 0 value
     D  idx                          10i 0 value options(*nopass)

      *****************************************************
      * Check error from XMLSERVICE.
      *
      * rc = isError(xml);
      *****************************************************
     D isError         PR            10i 0
     D  xml                                likeds(xml_Rec_t)

      *****************************************************
      * Copy error from XMLSERVICE.
      *
      * getErrMsg(xml:%addr(sErrMsg):%size(sErrMsg));
      *****************************************************
     D getErrMsg       PR
     D  xml                                likeds(xml_Rec_t)
     D  str                            *   value
     D  slen                         10i 0 value

      *****************************************************
      * Copy error CPF from XMLSERVICE (if possible).
      *
      * getErrCPF(xml:%addr(sErrCPF):%size(sErrCPF));
      *****************************************************
     D getErrCPF       PR
     D  xml                                likeds(xml_Rec_t)
     D  str                            *   value
     D  slen                         10i 0 value


Sample RPG program (zzrpgkit)

     H AlwNull(*UsrCtl)

      *****************************************************
      * Copyright (c) 2010, IBM Corporation
      * All rights reserved.
      *
      * Redistribution and use in source and binary forms, 
      * with or without modification, are permitted provided 
      * that the following conditions are met:
      * - Redistributions of source code must retain 
      *   the above copyright notice, this list of conditions 
      *   and the following disclaimer. 
      * - Redistributions in binary form must reproduce the 
      *   above copyright notice, this list of conditions 
      *   and the following disclaimer in the documentation 
      *   and/or other materials provided with the distribution.
      * - Neither the name of the IBM Corporation nor the names 
      *   of its contributors may be used to endorse or promote 
      *   products derived from this software without specific 
      *   prior written permission. 
      *
      * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
      * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
      * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
      * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
      * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
      * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
      * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
      * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
      * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
      * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
      * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
      * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
      * POSSIBILITY OF SUCH DAMAGE.
      *****************************************************

      *****************************************************
      * includes
      *****************************************************
      /copy rpgkit_h
      /copy zzmyauth_h

     D rc              s             10i 0 inz(XML_SUCCESS)

     D auth            ds                  likeds(xml_Auth_t)
     D xml             ds                  likeds(xml_Rec_t)

     D  CHAR1a         S              1a
     D  DEC7p4         S              7p 4        
     D  DEC12p2        S             12p 2
     D  sDEC7p4        S             64A        
     D  sDEC12p2       S             64A

     D  sULib          S           4096A
     D  sSLib          S           4096A

     D  sBuf           S          65000A

     D  sErrCPF        S              7A
     D  sErrMsg        S          65000A

      /free
       Monitor;
       // ----------------------------
       // get my authorization (any way you like) 
       auth = crtAuth1();

       // ----------------------------
       // CMD call 
       xml = crtXML(
             auth         // authorization (xml_Auth_t)
            :*BLANKS      // ipc route (private connect)
            :'*here'      // control (reserved words)
            :XML_4K       // size input xml (4k .. 15M)
            :XML_4K);     // size output xml (4k .. 15M)
       rc = crtCmd(xml    // see crtXML above
            :'chg1'       // unique var name for operation
            :'CHGLIBL LIBL(QTEMP XMLSERVICE)');
       rc = callXML(xml); // execute xmlservice call

       // get some return vars (any order, any subset)
       if isError(xml) = XML_SUCCESS;
         // no output this command
       else;
         // may not have CPF error='fast',
         // if needed use sloooow mode error='on'
         // begPgm(xml:...:XML_ERR_ON);
         getErrCPF(xml:%addr(sErrCPF):%size(sErrCPF));
         // full dump of XML error
         getErrMsg(xml:%addr(sErrMsg):%size(sErrMsg));
       endif;

       dltXML(xml);       // delete all memory used

       // ----------------------------
       // CMD call with output
       xml = crtXML(
             auth         // authorization (xml_Auth_t)
            :*BLANKS      // ipc route (private connect)
            :'*here'      // control (reserved words)
            :XML_4K       // size input xml (4k .. 15M)
            :XML_4K);     // size output xml (4k .. 15M)
       rc = crtCmd(xml    // see crtXML above
            :'rtv1'       // unique var name for operation
            :'RTVJOBA USRLIBL(?) SYSLIBL(?)');
       rc = callXML(xml); // execute xmlservice call

       // get some return vars (any order, any subset)
       if isError(xml) = XML_SUCCESS;
         sULib = *BLANKS;
         rc = getCmdStr(xml:'USRLIBL':%addr(sULib):%size(sULib));
         rc = getCmdStr(xml:'SYSLIBL':%addr(sSLib):%size(sSLib));
       else;
         // may not have CPF error='fast',
         // if needed use sloooow mode error='on'
         // begPgm(xml:...:XML_ERR_ON);
         getErrCPF(xml:%addr(sErrCPF):%size(sErrCPF));
         // full dump of XML error
         getErrMsg(xml:%addr(sErrMsg):%size(sErrMsg));
       endif;

       dltXML(xml);       // delete all memory used

       // ----------------------------
       // PASE call 
       xml = crtXML(
             auth         // authorization (xml_Auth_t)
            :*BLANKS      // ipc route (private connect)
            :'*here'      // control (reserved words)
            :XML_4K       // size input xml (4k .. 15M)
            :XML_15M);    // size output xml (4k .. 15M)
       rc = crtSH(xml     // see crtXML above
            :'sh1'        // unique var name for operation
            :'system -i "WRKSYSVAL OUTPUT(*PRINT)"');
       rc = callXML(xml); // execute xmlservice call

       // get some return vars (any order, any subset)
       if isError(xml) = XML_SUCCESS;
         sBUF = *BLANKS;
         rc = getSHStr(xml:'sh1':%addr(sBUF):%size(sBUF));
       else;
         // may not have CPF error='fast',
         // if needed use sloooow mode error='on'
         // begPgm(xml:...:XML_ERR_ON);
         getErrCPF(xml:%addr(sErrCPF):%size(sErrCPF));
         // full dump of XML error
         getErrMsg(xml:%addr(sErrMsg):%size(sErrMsg));
       endif;

       dltXML(xml);       // delete all memory used

       // ----------------------------
       // PGM call 
       //     D  INCHARA        S              1a
       //     D  INCHARB        S              1a
       //     D  INDEC1         S              7p 4        
       //     D  INDEC2         S             12p 2
       //     D  INDS1          DS                  
       //     D   DSCHARA                      1a
       //     D   DSCHARB                      1a           
       //     D   DSDEC1                       7p 4      
       //     D   DSDEC2                      12p 2            
       //      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       //      * main(): Control flow
       //      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       //     C     *Entry        PLIST                   
       //     C                   PARM                    INCHARA
       //     C                   PARM                    INCHARB
       //     C                   PARM                    INDEC1
       //     C                   PARM                    INDEC2
       //     C                   PARM                    INDS1
       xml = crtXML(
             auth         // authorization (xml_Auth_t)
            :*BLANKS      // ipc route (private connect)
            :'*here'      // control (reserved words)
            :XML_4K       // size input xml (4k .. 15M)
            :XML_4K);     // size output xml (4k .. 15M)
       rc = begPgm(xml:'zz1':'ZZCALL':'XMLSERVICE');

        rc = begParm(xml:'p1');
         CHAR1a = 'a';
         rc = addVal(xml:'INCHARA':'a':1:0:%addr(CHAR1a));
        rc = endParm(xml);

        rc = begParm(xml:'p2');
         CHAR1a = 'b';
         rc = addVal(xml:'INCHARB':'a':1:0:%addr(CHAR1a));
        rc = endParm(xml);

        rc = begParm(xml:'p3');
         DEC7p4 = 42.42;
         rc = addVal(xml:'INDEC1':'p':7:4:%addr(DEC7p4));
        rc = endParm(xml);

        rc = begParm(xml:'p4');
         DEC12p2 = 34.4;
         rc = addVal(xml:'INDEC2':'p':12:2:%addr(DEC12p2));
        rc = endParm(xml);

        rc = begParm(xml:'p5');
         rc = begDS(xml:'INDS1');
          CHAR1a = 'g';
          rc = addVal(xml:'DSCHARA':'a':1:0:%addr(CHAR1a));
          CHAR1a = 'h';
          rc = addVal(xml:'DSCHARB':'a':1:0:%addr(CHAR1a));
          DEC7p4 = 1.1111;
          rc = addVal(xml:'DSDEC1':'p':7:4:%addr(DEC7p4));
          DEC12p2 = 22.22;
          rc = addVal(xml:'DSDEC2':'p':12:2:%addr(DEC12p2));
         rc = endDS(xml);
        rc = endParm(xml);

       rc = endPgm(xml);

       rc = callXML(xml); // execute xmlservice call

       // get some return vars (any order, any subset)
       if isError(xml) = XML_SUCCESS;
         rc = getVal(xml:'DSCHARA':%addr(CHAR1a));
         rc = getVal(xml:'INDEC1':%addr(DEC7p4));
         rc = getVal(xml:'DSDEC2':%addr(DEC12p2));
         rc = getValStr(xml:'INDEC1':%addr(sDEC7p4):%size(sDEC7p4));
         rc = getValStr(xml:'DSDEC2':%addr(sDEC12p2):%size(sDEC12p2));
       else;
         // may not have CPF error='fast',
         // if needed use sloooow mode error='on'
         // begPgm(xml:...:XML_ERR_ON);
         getErrCPF(xml:%addr(sErrCPF):%size(sErrCPF));
         // full dump of XML error
         getErrMsg(xml:%addr(sErrMsg):%size(sErrMsg));
       endif;

       dltXML(xml);       // delete all memory used


       // ----------------------------
       // PGM call (error)
       xml = crtXML(
             auth         // authorization (xml_Auth_t)
            :*BLANKS      // ipc route (private connect)
            :'*here'      // control (reserved words)
            :XML_4K       // size input xml (4k .. 15M)
            :XML_4K);     // size output xml (4k .. 15M)
       rc = begPgm(xml:'bad1':'ZZMISS':'XMLSERVICE');
       rc = endPgm(xml);

       rc = callXML(xml); // execute xmlservice call

       // get some return vars (any order, any subset)
       if isError(xml) = XML_SUCCESS;
         // should not work
       else;
         // may not have CPF error='fast',
         // if needed use sloooow mode error='on'
         // begPgm(xml:...:XML_ERR_ON);
         getErrCPF(xml:%addr(sErrCPF):%size(sErrCPF));
         // full dump of XML error
         getErrMsg(xml:%addr(sErrMsg):%size(sErrMsg));
       endif;

       dltXML(xml);       // delete all memory used

       On-error;
       Endmon;

       return;
      /end-free