[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: XML Writer Service program



   Hi Nick
   clearSrvPgm, sorry I have changed the name.
   the service program is intended to work as a middleware in a
   CGIDEV2 based web 2.0 solution therefore the zhbgetinput that
   reads the variables from a HTTP/POST.
   I have moved the zhbGetInput to another subprocedure, getExtInput();
   so it dosn't interfeer when using the serviceprogram as a plain file
   generator.
   The "content/type ..." statement is a HTTP thing only, if you only
   make
   IFS files you do not need to tell the Apache server what's comming.
   Sorry for the # comment, the most correct encoding of comments in a
   XML document is <!-- any comment -->
   CGIDEV2 supports CODEPAGE as standard and there is no UNICODE
   CODEPAGE, I have made a change in my version of CGIDEV2 according
   to Scott's directions so it supports CCSID and by that 1208 (UTF-8).
   Scott's changes can be found here:
   http://forums.systeminetwork.com/isnetforums/showthread.php?p=227621
   I have also added support for XML nodes that has no children and
   has no value but only attributes like
   <grid design="BASICGRID">
           <gridField id="X0X0ID" comment="System Parameter" />
           <gridField id="X0XAID" comment="Application Id." />
   </grid>
   This is done by creating a xml nodes like
   xmlNode('grid':'design="BASICGRID"');
     xmlNode('gridField':'id="X0X0ID" comment="System Parameter"':'');
                                                                 ***
     xmlNode('gridField':'id="X0XAID" comment="Application id."':'');
                                                                ***
   xmlEndNode();
   I have also added a CDATA option to the xmlNode subprocedure:
    * STRUCTURED JSON SUPPORT
   d jsonNode        pr
   d  type                      32767  // value
   d  attribute                 32767  // value
   d  value                     32767  // value
   d  cdata                         1  // boolean, if true pass value as
   is in CDATA
   d  truncate                      1  // boolean, if false do not %trimr
   string
     xmlNode('abc':'':'&&>><<':*on);
   will generate

    <abc><![CDATA[&&>><<]]></abc>
   regards
   Henrik

   "Nick Runnalls" <nick@xxxxxxxxxx>
   Sent by: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx

   16-07-2009 03:30

                             Please respond to
        HTTPAPI and FTPAPI Projects <ftpapi@xxxxxxxxxxxxxxxxxxxxxx>

                                                                       To

   "'HTTPAPI and FTPAPI Projects'" <ftpapi@xxxxxxxxxxxxxxxxxxxxxx>

                                                                       cc

                                                                  Subject

   RE: XML Writer Service program

   Hi Henrik
   I have tried this and got it working, I had problems with clrSrvPgm()
   Should
   this be clearSrvPgm, when I changed it I still issues with
   nbrVars = zhbgetinput(savedquerystring:qusec); in service program, and
   commented it out, what is the effect of this.
   Also XML browser did not like first few lines of output. i.e.
                   Content-type: text/xml
                   # This is a generated xml-file   (I replaced this with
    echo('<!This
   is a generated xml-file of Deliverys from AWH Pty'); )
   I also changed the codepage to 819 instead of 1208 as this seemed to
   cause
   issues.
   Sorry bit rusty in this area. Thaks for your help.
   Nick Runnalls
   -----Original Message-----
   From: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx
   [mailto:ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of
   hr@xxxxxxxxxxxx
   Sent: Wednesday, 8 July 2009 12:24 AM
   To: HTTPAPI and FTPAPI Projects
   Subject: Re: XML Writer Service program
   Hi,
   enclosed is a service program that does the trick;
   Sample code
   --------------------------------------------------------
   clrSrvPgm();
   // setGlobalTab(*off);   // compress the file
   // setGlonalNL(*off);    // by omitting Tab's and CRLF
   // if you wish to send it out over HTTP
   setContent('text/xml');
   echo('# This is a generated xml-file');
   echo('');
   xmlNode('xml');
    xmlNode('header':'custNumber='+%char(cust));
      xmlNode('name':'':cuname);                   // "Jon & Susan"
      xmlNode('adress':'':cuadrs);
      select;
        when country = 'dk';
          xmlNode('zip':'list=dk':%char(cuzip));
        when country = 'usa';
          xmlNode('zip':'list=us':%char(cuzip));
      endsl;
    xmlEndNode();
   xmlEndNode();
   select;
    when output = 'file';               // Output to File
      echoToStmf('/testxml.xml':1208);    // most XML converters likes
   UTF-8
    when output = 'http';               // Output to HTTP buffer
      echoFini();
   endsl;
   Result:
   ---------------------------------------------------------
   Content-type: text/xml
   # This is a generated xml-file
   <xml>
          <header custNumber=123456>
                  <name>Jon &#38; Susan</name>
                  <adress>Stampedammen</adress>
                  <zip list=dk>1234</zip>
          </header>
   </xml>
   This code is done by a CGIDEV2 service extension program that handles
   not
   only the single node's but also the tree, so there is no need to
   insert tabs
   or to remember parent nodes when
   ending them with xmlEndNode() and it eliminates spelling
   errors between start and end nodes.
   It also automatically handles the special character incoding
   of strings in the XML.
   And there is no need for CGIDEV2 templates wich does it far
   easier to include/exclude elements by just using inline tests.
   Note:
   The enclosed basic service program is part of a larger WEB 2.0 (ext
   JS)
   project that will be released later this year and it
   is build on top of a modified CGIDEV2 (Scott's CCSID support
   modification for Unicode CCSID).
   Regards
   Henrik
   Nicolas Machado <nicolas.machado@xxxxxxxxxxxxx>
   Sent by: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx
   06-07-2009 16:34
   Please respond to
   HTTPAPI and FTPAPI Projects <ftpapi@xxxxxxxxxxxxxxxxxxxxxx>
   To
   HTTPAPI and FTPAPI Projects <ftpapi@xxxxxxxxxxxxxxxxxxxxxx>
   cc
   Subject
   XML Writer Service program
   Hi,
   I'm starting a project that need to write xml files.
   I know that there is no mora "rocket science" that wrinting to a
   stream
   file in teh IFS.
   But I'm wondering is someone has developed something like:
     xml =  pCreateXmlObject();
      pWriteStartElement(xml : 'Invoice') ;
      pWriteTag(xml : 'InvNro' : $InvoiceNumber ) ;
      pWriteEndElement(xml)
   To for example create this xml
      <Invoice>
            <InvNr>some value</InvNr>
      </Invoice>
   If anyone has something , please let me know.
   --
   .::.
   Nicolas Machado
   Metodo Argentina S.A.
   _____________________
   Tel: 02262 527431
   Necochea, Buenos Aires.
   ----------------------------------------------------------------------
   -
   This is the FTPAPI mailing list.  To unsubscribe, please go to:
   http://www.scottklement.com/mailman/listinfo/ftpapi
   ----------------------------------------------------------------------
   -
   ----------------------------------------------------------------------
   -
   This is the FTPAPI mailing list.  To unsubscribe, please go to:
   http://www.scottklement.com/mailman/listinfo/ftpapi
   ----------------------------------------------------------------------
   -
      *=====================================================================
      *  Project   : powerEXT®
      *  Title     : General Service Program/CGIDEV2 Ver
      *  Build     : 2009.07.16
      *
      *  Copyright © HR Software Development, Denmark
      *  Author    : Henrik Rützou
      *  License   : GNU GPL v3 license
      *  Website   : powerext.com
      *=====================================================================
     hnomain

      *=====================================================================
      * CGIDEV2 Service Program Includes
      *=====================================================================
      /copy qrpglesrc,hspecs
      /copy qrpglesrc,hspecsbnd

      * Global Variables
     d true            s              1    inz(*on)
     d false           s              1    inz(*off)

     d seed            s             10i 0

     d globalTabs      s              1
     d globalNL        s              1

     d tabPt           s             10I 0
     d tabHx           s              1    inz(x'05')
     d tabNL           s              1    inz(x'15')

     d htmlPt          s             10I 0
     d htmlTags        s           1024    varying dim(1000)

     d xmlPt           s             10I 0
     d xmlTags         s           1024    varying dim(1000)

     d jsonPt          s             10I 0
     d jsonTags        s           1024    varying dim(1000)
     d jsonComma       s              1    varying dim(1000)

      * GENERAL SERVICE
     d clearSrvPgm     pr

     d setContent      pr
     d  type                      32767    const options(*nopass) varying

     d setGlobalTab    pr
     d  boolean                       1    const options(*varsize) varying

     d setGlobalNL     pr
     d  boolean                       1    const options(*varsize) varying

     d getExtInput     pr

     d getExtVar       pr         32767
     d  var                         128    const options(*varsize) varying
     d  default                   32767    const options(*nopass)  varying

     d getExtVarNum    pr            30p 9
     d  var                         128    const options(*varsize) varying
     d  default                      30p 9 const options(*nopass)

     d setExtVar       pr
     d  var                          30    value varying
     d  string                    32767    const options(*varsize) varying

     d echo            pr
     d  string                    32767    const options(*varsize) varying
     d  tabs                          1    const options(*nopass)  varying
     d  NL                            1    const options(*nopass)  varying

     d echoTag         pr
     d  stmf                       1024    const varying
     d  section                    1000    value varying

     d echoSection     pr
     d  stmf                       1024    const varying
     d  section                    1000    const varying

     d echoFini        pr

     d echoToStmf      pr            10i 0
     d  stmf                       1024    const varying
     d  codePage                     10u 0 const options(*nopass)

     d tab             pr

     d tabEnd          pr

     d tabClear        pr

     d NL              pr         32767    varying

      * MISC
     d timeStamp       pr            26Z

     d uniqueKey       pr            32

     d qCmd            pr
     d  cmd                       32702    const options(*varsize) varying

      * STRUCTURED HTML SUPPORT
     d htmlNode        pr
     d  tag                       32767    const options(*varsize) varying
     d  attributes                32767    const options(*nopass)  varying
     d  string                    32767    const options(*nopass)  varying
     d  truncate                      1    const options(*nopass)  varying

     d htmlEndNode     pr
     d  tag                       32767    const options(*nopass) varying

      * STRUCTURED XML SUPPORT
     d xmlNode         pr
     d  tag                       32767    const options(*varsize) varying
     d  attributes                32767    const options(*nopass)  varying
     d  string                    32767    const options(*nopass)  varying
     d  cdata                         1    const options(*nopass)  varying
     d  truncate                      1    const options(*nopass)  varying

     d xmlEndNode      pr
     d  tag                       32767    const options(*nopass) varying

      * STRUCTURED JSON SUPPORT
     d jsonNode        pr
     d  type                      32767    const options(*varsize) varying
     d  attribute                 32767    const options(*nopass)  varying
     d  value                     32767    const options(*nopass)  varying
     d  truncate                      1    const options(*nopass)  varying

     d jsonEndNode     pr
     d  type                      32767    const options(*nopass) varying

      * STRING ENCODERS
     d encodeHTML      pr         32767    varying
     d  string                    32767    const options(*varsize) varying

     d encodeXML       pr         32767    varying
     d  string                    32767    const options(*varsize) varying

     d encodeJSON      pr         32767    varying
     d  string                    32767    const options(*varsize) varying

     d encodeJAVA      pr         32767    varying
     d  string                    32767    const options(*varsize) varying

     d encodeCSV       pr         32767    varying
     d  string                    32767    const options(*varsize) varying

      *=====================================================================
      * CGIDEV2 Service Program Includes
      *=====================================================================
      /copy qrpglesrc,prototypeb
      /copy qrpglesrc,usec
      /copy qrpglesrc,variables3

      *=====================================================================
      * clearSrvPgm
      *=====================================================================
     p clearSrvPgm     b                   export
     d clearSrvPgm     pi

     d i               s             10i 0
      /free

       globalTabs = true;
       globalNL = true;

       tabPt = 0;

       htmlPt = 0;
       xmlPt = 0;
       jsonPt = 0;

       for i = 1 to 1000;
         htmlTags(i) = '';
         xmlTags(i) = '';
         jsonTags(i) = '';
         jsonComma(i) = '';
       endfor;

      /end-free
     p                 e

      *=====================================================================
      * setContent
      *=====================================================================
     p setContent      b                   export
     d SetContent      pi
     d  type                      32767    const options(*nopass) varying

     d localType       s          32767    varying

     d wrkString       s          32767    varying
      /free

       if %parms >= 1;
         localType = type;
       else;
         localType = 'text/html';
       endif;

       clrHtmlBuffer();

       wrkString = 'Content-type: '
        + localType
        + tabNL
        + tabNL
       ;
       wrtNoSection(%addr(wrkString)+2:%len(wrkString));
       return;

      /end-free
     p                 e

      *=====================================================================
      * setGlobalTab
      *=====================================================================
     p setGlobalTab    b                   export
     d SetGlobalTab    pi
     d  boolean                       1    const options(*varsize) varying
      /free

       globalTabs = boolean;

      /end-free
     p                 e

      *=====================================================================
      * setGlobalNL
      *=====================================================================
     p setGlobalNL     b                   export
     d SetGlobalNL     pi
     d  boolean                       1    const options(*varsize) varying
      /free

       globalNL = boolean;

      /end-free
     p                 e

      *=====================================================================
      * getExtInput
      *=====================================================================
     p getExtInput     b                   export
     d getExtInput     pi

      /free

       nbrVars = zhbgetinput(savedquerystring:qusec);

      /end-free
     p                 e

      *=====================================================================
      * getExtVar
      *=====================================================================
     p getExtVar       b                   export
     d getExtVar       pi         32767
     d  var                         128    const options(*varsize) varying
     d  default                   32767    const options(*nopass)  varying

     d wrkString       s          32767    varying
      /free

       wrkString = '';
       if zhbGetVarCnt(var) < 1;
         if %parms >= 2;
           wrkString = default;
         endif;
       else;
         wrkString = zhbGetVar(var);
       endif;

       return wrkString;

      /end-free
     p                 e

      *=====================================================================
      * getExtVarNum
      *=====================================================================
     p getExtVarNum    b                   export
     d getExtVarNum    pi            30p 9
     d  var                         128    const options(*varsize) varying
     d  default                      30p 9 const options(*nopass)

     d wrkString       s          32767    varying
     d wrkNum          s             30p 9
      /free

       wrkNum = 0;
       if zhbGetVarCnt(var) < 1;
         if %parms >= 2;
           wrkNum = default;
         endif;
       else;
         wrkString = zhbGetVar(var);
         wrkNum = c2n2(wrkString);
       endif;

       return wrkNum;

      /end-free
     p                 e

      *=====================================================================
      * setExtVar
      *=====================================================================
     p setExtVar       b                   export
     d setExtVar       pi
     d  var                          30    value varying
     d  string                    32767    const options(*varsize) varying

     d wrkString       s          32767    varying
     d d               s             32
      /free

       wrkString = string;
       d = wrkString;
       // dsply d;
       updHtmlVar2(var:%addr(wrkString)+2:%len(wrkString));
       // updHtmlVar2('XML':%addr(wrkString)+2:%len(wrkString));
       // updHtmlVar('XML':'abc');

      /end-free
     p                 e

      *=====================================================================
      * echo Responce Write
      *=====================================================================
     p echo            b                   export
     d echo            pi
     d  string                    32767    const options(*varsize) varying
     d  tabs                          1    const options(*nopass)  varying
     d  NL                            1    const options(*nopass)  varying

     d localTabs       s              1    varying
     d localNL         s              1    varying

     d wrkString       s          32767    varying
     d i               s             10i 0
      /free

       if %parms >= 2;
         localTabs = tabs;
       else;
         localTabs = '';
       endif;

       if %parms >= 3;
         localNL = NL;
       else;
         localNL = '';
       endif;

       wrkString = '';
       select;
         when globalTabs = false;
         when localTabs = false;
         other;
           if tabPt > 0;
             for i = 1 to TabPt;
               wrkString += TabHx;
             endfor;
           endif;
       endsl;
       wrkString += string;
       select;
         when globalNL = false;
         when localNL = false;
         other;
           wrkString += TabNL;
       endsl;
       wrtNoSection(%addr(wrkString)+2:%len(wrkString));
       return;

      /end-free
     p                 e

      *=====================================================================
      * echoTag
      *=====================================================================
     p echoTag         b                   export
     d echoTag         pi
     d  stmf                       1024    const varying
     d  section                    1000    value varying

     d rc              s             10i 0
     d secDelimStart   s             20    varying inz('<!--#tag="')
     d secDelimEnd     s             20    varying inz('"-->')
     d varDelimStart   s             20    varying inz('<%$ ')
     d varDelimEnd     s             20    varying inz(' %>')
      /free

       gethtmlIFS(stmf
        :secDelimStart
        :secDelimEnd
        :varDelimStart
        :varDelimEnd
       );
       wrtSection(section);
       return;

      /end-free
     p                 e

      *=====================================================================
      * echoSection
      *=====================================================================
     p echoSection     b                   export
     d echoSection     pi
     d  stmf                       1024    const varying
     d  section                    1000    const varying

     d rc              s             10i 0
     d secDelimStart   s             20    varying inz('<!--#tag="')
     d secDelimEnd     s             20    varying inz('"-->')
     d varDelimStart   s             20    varying inz('<%$')
     d varDelimEnd     s             20    varying inz('%>')
      /free

       // gethtmlIFS(stmf
       // :secDelimStart
       // :secDelimEnd
        // :varDelimStart
        // :varDelimEnd
       // );
       wrtSection(section);
       return;

      /end-free
     p                 e

      *=====================================================================
      * echoFini
      *=====================================================================
     p echoFini        b                   export
     d echoFini        pi
      /free

       wrtSection('*fini');

      /end-free
     p                 e

      *=====================================================================
      * echoToStmf
      *=====================================================================
     p echoToStmf      b                   export
     d echoToStmf      pi            10i 0
     d  stmf                       1024    const varying
     d  codePage                     10u 0 const options(*nopass)

     d rc              s             10i 0
      /free

       rc = WrtHtmlToStmf(stmf:codePage);
       return rc;

      /end-free
     p                 e

      *=====================================================================
      * tab
      *=====================================================================
     p tab             b                   export
     d tab             pi
      /free

       tabPt += 1;

      /end-free
     p                 e

      *=====================================================================
      * tabEnd
      *=====================================================================
     p tabEnd          b                   export
     d tabEnd          pi
      /free

       tabPt -= 1;

      /end-free
     p                 e

      *=====================================================================
      * tabClear
      *=====================================================================
     p tabClear        b                   export
     d tabClear        pi
      /free

       tabPt = 0;

      /end-free
     p                 e

      *=====================================================================
      * NL New Line and Tabs
      *=====================================================================
     p NL              b                   export
     d NL              pi         32767    varying

     d wrkString       s          32767    varying
     d i               s             10i 0
      /free

       wrkString = tabNL;

       if tabPt > 0;
         for i = 1 to TabPt;
           wrkString += TabHx;
         endfor;
       endif;

       return wrkString;

      /end-free
     p                 e

      *=====================================================================
      * timeStamp
      *=====================================================================
     p timeStamp       b                   export
     d timeStamp       pi            26Z

      * TimeStamp Handler
     d GetTimeOfDay    PR            10I 0 ExtProc('gettimeofday')
     d TimeVal                        8A
     d TimeZone                       1

     d TimeConv        DS             8
     d TimeSec                       10I 0
     d TimeMsec                      10I 0

     d TimeRc          S             10I 0
     d TimeVal         S              8A
     d TimeZone        S              1
     d TimeOffset      S               Z   Inz(Z'1970-01-01-00.00.00.000000')
     d TimeStampW      S               Z

     d SysValData      S             33A
     d SysValDataLen   S              9B 0 Inz(%Len(SysValData))
     d SysNbrOfSysVal  S              9B 0 Inz(1)
     d SysValues       S             10    Inz('QUTCOFFSET')
     d SysApiError     S             80

     d SysValDataDS    DS             5
      * redefines SysValData
     d   UtcSign                      1A
     d   UtcHours                     2S 0
     d   UtcMinutes                   2S 0

     d QWcrSVal        PR                  ExtPgm('QWCRSVAL')
     d SysValData                    33A
     d SysValDataLen                  9B 0
     d SysNbrOfSysVal                 9B 0
     d SysValues                     10
     d SysApiError                   80
      /free

       // Get Unix Time
       TimeRc = GetTimeOfDay(TimeVal:TimeZone);
       TimeConv = TimeVal;

       // Generate TimeStamp
       TimeStampW = TimeOffSet;
       TimeStampW += %seconds(TimeSec);
       TimeStampW += %mseconds(TimeMsec);

       // Adjust with Sysvalue UTC Offset
       QWCRSVAL(SysValData:
        SysValDataLen:
        SysNbrOfSysVal:
        SysValues:
        SysApiError);

       if %Subst(SysApiError:9:7) = ' ';
         SysValDataDs  = %Subst(SysValData:25:5);

         if UtcSign = '+';
           TimeStampW += %hours(UtcHours);
           TimeStampW += %minutes(UtcMinutes);
         endif;
         if UtcSign = '-';
           TimeStampW -= %hours(UtcHours);
           TimeStampW -= %minutes(UtcMinutes);
         endif;
       endif;

       return timeStampW;

      /end-free
     p                 e

      *=====================================================================
      * uniqueKey
      *=====================================================================
     p uniqueKey       b                   export
     d uniqueKey       pi            32

      * uniqueKey Handler
     d uniqueKeyW      s             32
     d uniDateStmp     s               z
     d year            s              4s 0
     d month           s              2s 0
     d day             s              2s 0
     d hour            s              2s 0
     d minute          s              2s 0
     d second          s              2s 0
     d msecond         s              6s 0

     d getRandomNum    pr                  extproc('CEERAN0')
     d  seed                         10i 0
     d  randomNum                     8F

     d randomNum       s              8F
      /free

       if seed = 0;
         uniDateStmp = timeStamp();
         seed = %subdt(uniDateStmp:*MS);
       endif;
       getRandomNum(seed:randomNum);

       uniDateStmp = timeStamp();
        year = %subdt(uniDateStmp:*Y);
        month = %subdt(uniDateStmp:*M);
        day = %subdt(uniDateStmp:*D);
        hour = %subdt(uniDateStmp:*H);
        minute = %subdt(uniDateStmp:*MN);
        second = %subdt(uniDateStmp:*S);
        msecond = %subdt(uniDateStmp:*MS);

       uniqueKeyW = %editc(seed:'X')
        + %editc(month:'X')
        + %editc(msecond:'X')
        + %editc(year:'X')
        + %editc(day:'X')
        + %editc(second:'X')
        + %editc(minute:'X')
        + %editc(hour:'X')
        + %subst(%editc(seed:'X'):9:2)
       ;

       return uniqueKeyW;

      /end-free
     p                 e

      *=====================================================================
      * Call OS Command
      *=====================================================================
     p qCmd            b                   export
     d qCmd            pi
     d  cmd                       32702    const options(*varsize) varying

     d qCmdExc         pr                  extpgm('QCMDEXC')
     d  cmdRun                    32702    const options(*varsize)
     d  cmdLen                       15p 5 const
     d  cmdDbcs                       3    const options(*nopass)

      /free

       qCmdExc(cmd:%len(%trim(cmd)));

      /end-free
     p                 e

      *=====================================================================
      * Structured HTML Support
      *=====================================================================
     p htmlNode        b                   export
     d htmlNode        pi
     d  tag                       32767    const options(*varsize) varying
     d  attributes                32767    const options(*nopass)  varying
     d  string                    32767    const options(*nopass)  varying
     d  truncate                      1    const options(*nopass)  varying

     d localAttr       s          32767    varying
     d localString     s          32767    varying
     d localStringPas  s              1
     d localTrunc      s              1    varying

     d wrkString       s          32767    varying
      /free

       if %parms >= 2;
         localAttr = attributes;
       else;
         localAttr = '';
       endif;

       if %parms >= 3;
         localStringPas = true;
         localString = string;
       else;
         localStringPas = false;
         localString = '';
       endif;

       if %parms >= 4;
         localTrunc = truncate;
       else;
         localTrunc = '';
       endif;

       // Start The Tag
       wrkString = '<' + tag;

       // Handles the attribute
       if localAttr <> '';
         wrkString += ' ' + %trimr(localAttr);
       endif;

       // End Initial Tag
       wrkString += '>';

       // Handle the String
       if localStringpas = true;
         if localTrunc = false;
           wrkString += encodeHTML(localString);
         else;
           wrkString += encodeHTML(%trimr(localString));
         endif;
         wrkString += '</' + tag + '>';
       endif;

       echo(wrkString);

       // Handles Indention and Pointers
       if localStringPas = false;
         tabPt += 1;
         htmlPt += 1;
         htmlTags(htmlPt) = tag;
       endif;

       return;

      /end-free
     p                 e

      *=====================================================================
      * html - End Html Node
      *=====================================================================
     p htmlEndNode     b                   export
     d htmlEndNode     pi
     d  tag                       32767    const options(*nopass) varying

     d localTag        s          32767    varying

     d wrkString       s          32767    varying
      /free

       if %parms >= 1;
         localTag = tag;
       else;
         if htmlPt >= 1;
           localTag = htmlTags(htmlPt);
         else;
           localTag = '';
         endif;
       endif;

       tabPt -= 1;
       htmlPt -= 1;

       wrkString = '</' + localTag + '>';

       echo(wrkString);

       return;

      /end-free
     p                 e

      *=====================================================================
      * Structured XML Support
      *=====================================================================
     p xmlNode         b                   export
     d xmlNode         pi
     d  tag                       32767    const options(*varsize) varying
     d  attributes                32767    const options(*nopass)  varying
     d  string                    32767    const options(*nopass)  varying
     d  cdata                         1    const options(*nopass)  varying
     d  truncate                      1    const options(*nopass)  varying

     d localAttr       s          32767    varying
     d localString     s          32767    varying
     d localStringPas  s              1
     d localCdata      s              1    varying
     d localTrunc      s              1    varying

     d wrkString       s          32767    varying
      /free

       if %parms >= 2;
         localAttr = attributes;
       else;
         localAttr = '';
       endif;

       if %parms >= 3;
         localStringPas = true;
         localString = string;
       else;
         localStringPas = false;
         localString = '';
       endif;

       if %parms >= 4
         and cdata > '';
           localcdata = cdata;
       else;
         localcdata = false;
       endif;

       if %parms >= 5;
         localTrunc = truncate;
       else;
         localTrunc = '';
       endif;

       // Start The Tag
       wrkString = '<' + tag;

       // Handles the attribute
       if localAttr <> '';
         wrkString += ' ' + %trimr(localAttr);
       endif;

       // End Initial Tag
       if localStringPas = true
         and localString > ''
         or localStringPas = false;
           wrkString += '>';
       endif;

       // Handle the String
       if localStringPas = true;
         if localcdata = false;
           if localTrunc = false;
             wrkString += encodeXML(localString);
           else;
             wrkString += encodeXML(%trimr(localString));
           endif;
         else;
             wrkString += '<![CDATA[' + localString + ']]>';
         endif;
         if localString > '';
           wrkString += '</' + tag + '>';
         else;
           wrkString += ' />';
         endif;
       endif;

       echo(wrkString);

       // Handles Indention and Pointers
       if localStringPas = false;
         tabPt += 1;
         xmlPt += 1;
         xmlTags(xmlPt) = tag;
       endif;

       return;

      /end-free
     p                 e

      *=====================================================================
      * End Xml Node
      *=====================================================================
     p xmlEndNode      b                   export
     d xmlEndNode      pi
     d  tag                       32767    const options(*nopass) varying

     d localTag        s          32767    varying

     d wrkString       s          32767    varying
      /free

       if %parms >= 1;
         localTag = tag;
       else;
         if xmlPt >= 1;
           localTag = xmlTags(xmlPt);
         else;
           localTag = '';
         endif;
       endif;

       tabPt -= 1;
       xmlPt -= 1;

       wrkString = '</' + localTag + '>';

       echo(wrkString);

       return;

      /end-free
     p                 e

      *=====================================================================
      * Declare Object, Array, String, Number, Boolean (true, false, null)
      *=====================================================================
     p jsonNode        b                   export
     d jsonNode        pi
     d  type                      32767    const options(*varsize) varying
     d  attribute                 32767    const options(*nopass)  varying
     d  value                     32767    const options(*nopass)  varying
     d  truncate                      1    const options(*nopass)  varying

     d localAttr       s          32767    varying
     d localVal        s          32767    varying
     d localTrunc      s              1    varying

     d wrkString       s          32767    varying
      /free

       if %parms >= 2;
         localAttr = attribute;
       else;
         localAttr = '';
       endif;

       if %parms >= 3;
         localVal = value;
       else;
         localVal = '';
       endif;

       if %parms >= 4;
         localTrunc = truncate;
       else;
         localTrunc = '';
       endif;

       // Handles comma's as prefix
       if jsonPt > 0;
         wrkString = jsonComma(jsonPt);
         jsonComma(jsonPt) = ',';
       else;
         wrkString = '';
       endif;

       // Handles the attribute
       if localAttr <> '';
         wrkString += '"' + %trimr(localAttr) + '": ';
       endif;

       // Handles the object model
       select;
         when type = '*array';
           wrkString += '[';
         when type = '*object';
           wrkString += '{';
         when type = '*string';
           if localTrunc = false;
             wrkString += '"' + encodeJSON(localVal) + '"';
           else;
             wrkString += '"' + encodeJSON(%trimr(localVal)) + '"';
           endif;
         when type = '*number';
           wrkString += localVal;
         when type = '*boolean';
           wrkString += localVal;
         other;
           wrkString += '***Error***';
       endsl;

       echo(wrkString);

       // Handles Indention and Pointers
       if type = '*array' or type = '*object';
         tabPt += 1;
         jsonPt += 1;
         jsonComma(jsonPt) = '';
         jsonTags(jsonPt) = type;
       endif;

       return;

      /end-free
     p                 e

      *=====================================================================
      * json - End Object or Array Declaration
      *=====================================================================
     p jsonEndNode     b                   export
     d jsonEndNode     pi
     d  type                      32767    const options(*nopass) varying

     d localType       s          32767    varying

     d wrkString       s          32767    varying
      /free

       if %parms >= 1;
         localType = type;
       else;
         if jsonPt >= 1;
           localType = jsonTags(jsonPt);
         else;
           localType = '';
         endif;
       endif;

       select;
         when localType = '*array';
           tabPt -= 1;
           jsonPt -= 1;
           wrkString = ']';
         when localType = '*object';
           tabPt -= 1;
           jsonPt -= 1;
           wrkString = '}';
         other;
           wrkString = '***Error***';
       endsl;
       echo(wrkString);
       return;

      /end-free
     p                 e

      *=====================================================================
      * encode HTML Character String
      *=====================================================================
     p encodeHTML      b                   export
     d encodeHTML      pi         32767    varying
     d  string                    32767    const options(*varsize) varying

     d wrkString       s          32767    varying
     d i               s             10i 0
     d c               s              1
     d c_prev          s              1
      /free

       for i = 1 to %len(string);
         c = %subst(string:i:1);

         // special character encoding
         select;

           // First blank, pass as blank
           when c = *blank and c_prev <> *blank;
             wrkString += ' ';

           // Following Blanks
           when c = *blank;
             wrkString += '&#160;';

           // " &#34;  special entity &quot;
           when c = '"';
             wrkString += '&quot;';

           // & &#38;  special entity &amp;
           when c = '&';
             wrkString += '&amp;';

           // ' &#39;
           when c = '''';
             wrkString += '&#39;';

           // < &#60;  special entity &lt;
           when c = '<';
             wrkString += '&lt;';

           // > &#62;  special entity &gt;
           when c = '>';
             wrkString += '&gt;';

           // [ &#91;
           when c = '[';
             wrkString += '&#91;';

           // ] &#93;
           when c = ']';
             wrkString += '&#93;';

           // all others
           other;
             wrkString += c;
         endsl;

       c_prev = c;

       endfor;
       return wrkString;

      /end-free
     p                 e

      *=====================================================================
      * encode XML Character String
      *=====================================================================
     p encodeXML       b                   export
     d encodeXML       pi         32767    varying
     d  string                    32767    const options(*varsize) varying

     d wrkString       s          32767    varying
     d i               s             10i 0
     d c               s              1
     d c_prev          s              1
      /free

       for i = 1 to %len(string);
         c = %subst(string:i:1);

         // special character encoding
         select;

           // First blank, pass as blank
           when c = *blank and c_prev <> *blank;
             wrkString += ' ';

           // Following Blanks
           // when c = *blank;
           //  wrkString += '&#160;';

           // " &#34;  special entity &quot;
           when c = '"';
             wrkString += '&quot;';

           // & &#38;  special entity &amp;
           when c = '&';
             wrkString += '&amp;';

           // ' &#39;
           when c = '''';
             wrkString += '&#39;';

           // < &#60;  special entity &lt;
           when c = '<';
             wrkString += '&lt;';

           // > &#62;  special entity &gt;
           when c = '>';
             wrkString += '&gt;';

           // [ &#91;
           when c = '[';
             wrkString += '&#91;';

           // ] &#93;
           when c = ']';
             wrkString += '&#93;';

           // all others
           other;
             wrkString += c;
         endsl;

       c_prev = c;

       endfor;
       return wrkString;

      /end-free
     p                 e

      *=====================================================================
      * encode JSON Character String
      *=====================================================================
     p encodeJSON      b                   export
     d encodeJSON      pi         32767    varying
     d  string                    32767    const options(*varsize) varying

     d wrkString       s          32767    varying
     d i               s             10i 0
     d c               s              1
      /free

       for i = 1 to %len(string);
         c = %subst(string:i:1);

         // special character encoding
         select;

           // " &#34;  special entity &quot;
           when c = '"';
             wrkString += '\"';

           // \ &#92;
           when c = '\';
             wrkString += '\\';

           // all others
           other;
             wrkString += c;
         endsl;

       endfor;
       return wrkString;

      /end-free
     p                 e

      *=====================================================================
      * encode JAVA Character String
      *=====================================================================
     p encodeJAVA      b                   export
     d encodeJAVA      pi         32767    varying
     d  string                    32767    const options(*varsize) varying

     d wrkString       s          32767    varying
     d i               s             10i 0
     d c               s              1
      /free

       for i = 1 to %len(string);
         c = %subst(string:i:1);

         // special character encoding
         select;

           // " &#34;  special entity &quot;
           when c = '"';
             wrkString += '\u0022';

           // ' &#39;
           when c = '''';
             wrkString += '\u0027';

           // \ &#92;
           when c = '\';
             wrkString += '\u005c';

           // all others
           other;
             wrkString += c;
         endsl;

       endfor;
       return wrkString;

      /end-free
     p                 e

      *=====================================================================
      * encode CSV Character String
      *=====================================================================
     p encodeCSV       b                   export
     d encodeCSV       pi         32767    varying
     d  string                    32767    const options(*varsize) varying

     d wrkString       s          32767    varying
     d i               s             10i 0
     d c               s              1
      /free

       for i = 1 to %len(string);
         c = %subst(string:i:1);

         // special character encoding
         select;

           // " &#34;  special entity &quot;
           when c = '"';
             wrkString += '""';

           // all others
           other;
             wrkString += c;
         endsl;

       endfor;
       return wrkString;

      /end-free
     p                 e
-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------