CELSIUS

This example program demonstrates the basic structure of an RPG program utilizing RPG-XML Suite to compose an XML request, call a remote web service, and parse the response XML with event-based parsing.

CELSIUS Program

#
     H DEBUG(*YES) DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

      /DEFINE RXSV6R1

      /copy QRPGLECPY,RXSCB
      /copy QRPGLETPL,CELSIUS

     D Template        PR
     D  p                                  Like(RXS_TEMPLATE_PARM)

     D XmlHandler      PR
     D  pType                        10A   Value
     D  pXPath                     1024A   Value Varying
     D  pData                          *   Value
     D  pDataLen                     10I 0 Value

     D gFahrenheit     S             10I 0
     D gCelsius        S             10I 0
     D gXmlRequest     S                   Like(RXS_Var64Kv_t)
     D gXmlResponse    S                   Like(RXS_Var64Kv_t)


     D ComposeDS       DS                  LikeDS(RXS_ComposeDS_t)
     D TransmitDS      DS                  LikeDS(RXS_TransmitDS_t)
     D ParseDS         DS                  LikeDS(RXS_ParseDS_t)
     D ErrorDS         DS                  LikeDS(RXS_CatchThrowErrorDS_t)

      /free

        *Inlr = *On;

        monitor;

          gFahrenheit = 100;

          exsr compose;

          exsr transmit;

          exsr parse;

          RXS_ResetDS( ErrorDS : RXS_DS_TYPE_CATCHTHROWERROR );
          ErrorDS.MessageId = 'RXS9897';
          ErrorDS.MessageData = 'Celsius Temp: '
            + %trim ( %editc( gCelsius : '3' ) + '°');
          ErrorDS.ThrowToCaller = RXS_YES;
          RXS_Throw( ErrorDS );
        on-error;

        endmon;


        begsr compose;

          RXS_ResetDS( ComposeDS : RXS_DS_TYPE_COMPOSE );
          ComposeDS.TemplateProcedure = %paddr(Template);
          RXS_StartComposeEngine(ComposeDS);

          RXS_ComposeVariable( fahrenheit : %Char(gFahrenheit) );
          RXS_ComposeSection( content );

          RXS_GetComposeBuffer(gXmlRequest);

        endsr;


        begsr transmit;

          RXS_ResetDS( TransmitDS : RXS_DS_TYPE_TRANSMIT );
          TransmitDS.URI =
            'http://www.w3schools.com/webservices/tempconvert.asmx';
          TransmitDS.HeaderSOAPAction =
            '"http://www.w3schools.com/webservices/FahrenheitToCelsius"';
          TransmitDS.LogFile = '/tmp/celsius.txt';
          TransmitDS.HeaderContentType = 'text/xml; charset=utf-8';
          TransmitDS.RequestCcsid = RXS_CCSID_UTF8;
          RXS_Transmit( gXmlResponse : gXmlRequest : TransmitDS );

        endsr;

        begsr parse;

          RXS_ResetDS( ParseDS : RXS_DS_TYPE_PARSE );
          ParseDS.GlobalHandler = %Paddr( XmlHandler );
          RXS_Parse( gXmlResponse : ParseDS );

        endsr;

      /end-free

     P XmlHandler      B
     D XmlHandler      PI
     D  pType                        10A   Value
     D  pXPath                     1024A   Value Varying
     D  pData                          *   Value
     D  pDataLen                     10I 0 Value
     D
     D parsed          S                   Like(RXS_Var1Kv_t)
      /free

        if pXPath =
           '/Envelope/Body/FahrenheitToCelsiusResponse' +
           '/FahrenheitToCelsiusResult/';

          // Calling RXS_STR in the V6R1-style forces you to use an
          //  intermediate variable when you need to convert type to
          //  integer or decimal. In V7R1-style, the below two lines of
          //  code would be a single line that looks like this:
          //      gCelsius = %Int( RXS_STR( pData : pDataLen ) );
          RXS_STR( parsed : pData : pDataLen );
          gCelsius = %Int( parsed );
        endif;

      /end-free
     P                 E

     P Template        B
     D                 PI
     D  p                                  Like(RXS_TEMPLATE_PARM)

       // Template RPG source was created from the actual template
       //  STMF using the following command:

       //     CRTRPGTPL STMF('/www/rxs/templates/geturi2.tpl')
       //       FILE(RXS3/QRPGLETPL) MBR(CELSIUS)

       // The RPG Template source is copied from QRPGLETPL by using
       //  /copy once in the D-specs and again below.

      /copy QRPGLETPL,CELSIUS

     P                 E

CELSIUS Template

#
      /IF NOT DEFINED(CELSIUS)
      /DEFINE CELSIUS
     D
     D                 DS
     D  CONTENT...
     D                               50A   Varying
     D
     D                 DS
     D  fahrenheit...
     D                               30A   Varying
      /EOF
      /ENDIF
      /free

        CONTENT =
          'CONTENT';
        fahrenheit =
          'fahrenheit';

       p  = '';
       p += '::CONTENT' + x'15';
       p += '<?xml version="1.0" encoding="utf-8"?>' + x'15';
       p += '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-i';
       p += 'nstance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:';
       p += 'soap="http://schemas.xmlsoap.org/soap/envelope/">' + x'15';
       p += '  <soap:Body>' + x'15';
       p += '    <FahrenheitToCelsius xmlns="https://www.w3schools.com/';
       p += 'xml/">' + x'15';
       p += '      <Fahrenheit>' + '.:fahrenheit:.' + '</Fahrenheit>' + x'15';
       p += '    </FahrenheitToCelsius>' + x'15';
       p += '  </soap:Body>' + x'15';
       p += '</soap:Envelope>' + x'15';

      /end-free