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

Re: Advice on how to process xsd:base64Binary XML element retrieved from a web service.



   Hello Paul,
   1) Sorry about the data type... should've been A=alphanumeric.   I
   must've forgotten that.
   2) I have no way of knowing what the data is or how you plan to use it,
   so I'm not really sure how to help you here.  You say it's XML -- okay,
   so what do you want to do with the XML?  If the goal is to parse it,
   then either save it into a variable, and pass that into an XML parser,
   or save it to a file (which would be much easier if the data isn't
   already EBCDIC -- though, that'd also run slightly slower.)
   3) To get this from the pointer, you need a based variable and you need
   to use %SUBST.
   D var             s             50a   based(p_var)
   D count           s              9p 0
   D transactionId   s             15p 0
    /free
         .
         .
         if name = 'count';
           p_var = value.data;
           count = %dec( %subst(var:1:value.len): 9 : 0 );
         elseif name = 'transactionIdOut';
           p_var = value.data;
           transactionId = %dec( %subst(var:1:value.len) : 15 : 0 );
         .
         .
   Note: All of this is off the top of my head and untested.  It's
   expected that you will be able to troubleshoot/fix any problems with
   it.

   On 12/16/2013 3:32 PM, [1]PReid@xxxxxxxxxxxx wrote:

   Hello again.
   I feel like I'm getting closer with this, but I'm still not there. Just
   to refresh your memory the Response XML that I get back looks like
   this:
    <soapenv:Body>
     <dequeue2Response>
        <dequeue2Return>
           <count>6</count>

   <transactions>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz...=</transactions>
            <transactionIdOut>58744654</transactionIdOut>
        </dequeue2Return>
     </dequeue2Response>
   </soapenv:Body>
   I implemented the code that Scott recommended into my program, and I
   think it is working, I just have a few questions.
   #1. I could not define the "resultVar" variable as it was shown below
   (without a Variable Type). I kept getting the following errors:
    NF3391E The LEN keyword is valid only for Data Structures, or for type
   A, C, or G; keyword is ignored.
    RNF3365E Keyword VARYING is allowed only for an item defined as
   character, graphic, or UCS-2.
    RNF3438E LIKE keyword is expected for field RESULTVAR but not found;
   definition is ignored.
   I defined it as Variable Type "C" which i believe means UCS-2...but I'm
   not sure if this is correct. It might depend on question #2 below.

   #2. The "transactions" element is base64 encoded and I believe that the
   example code that Scott showed me is in fact decoding it...I am just at
   a loss as to what to do with it. The data that is encoded in the
   element, is itself,  an XML document. I am thinking that I should write
   this out to a temporary file on the IFS and then parse it later in the
   program?,..but I don't know how to output an XML to the IFS?...I'm also
   not sure if this is the best way to handle this situation...In the end
   I want to write this data into files on our IBMi.

   #3. The "count" and "transactionIdOut" elements are not base64 encoded,
   however; I do need the data returned in these fields. With the changes
   that I've made to my "Incoming" procedure, I can't seem to retrieve the
   data stored in the "value" field. How do I get these values out of the
   new "value" data structure?
   Below I am including...what I think...is the relevant portions of code
   from my program. I can supply the entire program if you want.
   *
   *----------------------------------------------------------------------
   --*
   *
   D Incoming        PR
   D   rate                         8F
   D   depth                       10I 0 value
   D   name                      1024A   varying const
   D   path                     24576A   varying const
   D   value                             likeds(Xmlstring_t)
   D   attrs                         *   dim(32767)
   D                                     const options(*varsize)
   *
   * Log.
   D dequeue2...
   D                 S           1000A   varying
   *
   * Can't figure out how to get the data into these fields.
   D count...
   D                 S              5P 0 inz(*zeros)
   D transactionIdOut...
   D                 S             17P 0 inz(*zeros)
   *
   * Not sure if resultVar is defined correctly?
   D resultVar       S               C    len(2000000) varying
   D decodedLen      S             10I 0
   *
   *----------------------------------------------------------------------
   --*
   *
   // Write out a Log.
      dequeue2 = '/home/PAULRE/dequeue2.txt';
      http_debug(*ON : dequeue2);
   // Change the way the XML parser returns the data.
   // We need to use pointer since it is so large...
      http_XmlReturnPtr(*on);
   // Post.
      rc = http_url_post_xml(
          '[2]https://www.myshawtracking.ca:443/otsWebWS/services/OTSWebSvcs'
         : %addr(SOAP) + 2
         : %len(SOAP)
         : *NULL
         : %paddr(Incoming)
         : %addr(rate)
         : HTTP_TIMEOUT
         : HTTP_USERAGENT
         : 'text/xml'
         : '[3]http://www.qualcomm.com/dequeue2');
   // Success!!!
      if rc = 1;
   *
   *----------------------------------------------------------------------
   --*
   *
   P Incoming        B
   *
   D Incoming        PI
   D   rate                         8F
   D   depth                       10I 0 value
   D   name                      1024A   varying const
   D   path                     24576A   varying const
   D   value                             likeds(XmlString_t)
   D   attrs                         *   dim(32767)
   D                                     const options(*varsize)
   *
   /free
       // This value is not base64 encoded.
       // I can't figure out how to get data into this field.
       if name = 'count';
          // count = %dec(value:5:0);
       // This value is base 64 encoded, I think this is working, and the
   data is
       // in resultVar...now what do I do with it?
       elseif name = 'transactions';
          %len(resultVar) = %len(resultVar : *MAX);
          decodedLen = base64_decode( value.data
                                    : value.len
                                    : %addr(resultVar : *data)
                                    : %len(resultVar : *MAX) );
          %len(resultVar) = decodedLen;
       // This value is not base64 encoded - not sure how to retrieve it?
       // I can't figure out how to get data into this field.
       elseif name = 'transactionIdOut';
          // transactionIdOut = %dec(value:17:0);
       endif;
   /end-free
   *
   P Incoming        E
   Thanks very much for your time. If there is any more information you
   need, just let me know.
   Have a great day!
   ___________________________________________________________
   Paul Reid
   Application Developer III
   Erb Group of Companies | 290 Hamilton Road | New Hamburg, Ontario | N3A
   1A2
   Phone: 519.662.6133 ext. 2363
   Web: [1][4]http://www.erbgroup.com/
   From:        Scott Klement [5]<sk@xxxxxxxxxxxxxxxx>
   To:        HTTPAPI and FTPAPI Projects [6]<ftpapi@xxxxxxxxxxxxxxxxxxxxxx>
   Date:        12/13/2013 12:56 AM
   Subject:        Re: Advice on how to process xsd:base64Binary XML
   element retrieved        from a web service.
   Sent by:        [7]ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx
     __________________________________________________________________

   hi Paul,
   HTTPAPI was originally written for OS/400 V4R2, and therefore does not
   "directly" support variables longer than 65535 characters long.
   However,
   in many cases HTTPAPI does have pointer-based interfaces that allow
   data
   as large as 16 MB to be returned -- so in order to handle data "up to
   approx 1 MB" you will want to use the pointer-based interfaces.  You
   can
   use them in conjunction with V7R1's support for large variables.
   Steps:
   1) Before calling http_url_post_xml(), you should call
   http_XmlReturnPtr(*ON).  What this does is change the way the XML
   parser
   returns data.  Instead of returning as a 65535 character string, it
   will
   now return it as a data structure, that has subfield for a pointer, and
   a subfield with a 10i 0 integer containing the length of the string in
   bytes.
   D XmlString_t     ds                  qualified Template
   D   Data                          *
   D   Len                         10i 0
   2) Change your 'Incoming' procedure (NOTE: you can call this procedure
   whatever you like, it does not have to be 'Incoming', that was just a
   name I used as an example) to receive this data structure in place of
   the 'value' string.
   D Incoming        PR
   D   rate 8F
   D   depth                       10I 0 value
   D   name                      1024A   varying const
   D   path                     24576A   varying const
   D   value likeds(XmlString_t)
   D   attrs                         * dim(32767)
   D                                     const options(*varsize)
   3) Now that 'value' is coming in as a pointer, it can be as large as
   you
   want.  You can now pass the 'value' parameter to tbe base64_decode
   procedure to eliminate the base64 encoding. Personally I like to use a
   VARYING variable for this sort of thing, and there's a trick to working
   with VARYING as a pointer...   you need to set it's length to the
   maximum length first, then pass the address of only the data portion,
   then set it's length back to the returned length.
   D resultVar       s                   len(2000000) varying
        %len(resultVar) = %len(resultVar: *MAX);
        decodedlen = base64_decode( value.data
                                  : value.len
                                  : %addr(resultVar: *data)
                                  : %len(ResultVar: *MAX) );
        %len(resultVar) = decodedlen;
   4) Now you have the decoded data in 'resultVar'.  However, you should
   know that this data will have the exact same binary value that it had
   when it was encoded.  If your data is text and the sender had it
   encoded
   in ASCII (or Unicode), then your data in resultVar will in ASCII, so
   you'll probably want to translate it to EBCDIC next.
   If the data in resultVar is not text, like an image, PDF, Word
   Document,
   sound file, etc...  then you won't want to translate it to EBCDIC, as
   that would corrupt the data.  (That is what is meant by 'binary')
   5) Not sure what you want to do next, it'll depend on the purpose of
   this data.  Should it be written to the IFS?  Stored in a BLOB?  So
   I'll
   leave that part as an exercise for you.
   Good luck....
   On 12/12/2013 9:48 AM, [8]PReid@xxxxxxxxxxxx wrote:
   >     Hello everyone. I am not very experienced with Web Services so
   bear
   >     with me. I did a fair bit of research on the various forums
   before
   >     posting, but I failed to find a good example of what I am looking
   for.
   >     I'm hoping that someone can help, possibly with an example.
   >     I am predominately an RPG programmer. We are running an IBM Power
   7 at
   >     V7R1, and I have Scott's HTTPAPI V1.24 downloaded and installed.
   I am
   >     using HTTPAPI to consume another Web Service and it works
   beautifully.
   >     My latest challenge it that I have consume a Web Service that
   includes
   >     an element in the XML response that is data type xsd:base64Binary
   and
   >     I'm not really sure how to do it. The WSDL for this web service
   is:
   >
   [1][2][9]https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/O
   TSW
   >     ebSvcs.wsdl
   >     The WIKI for this Web Service is:
   >
   [2][3][10]https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+De
   que
   >     ue
   >     The method that I must consume is named DEQUEUE2.
   >     I have created an RPG program that POSTS a request to the Web
   Service
   >     using the following HTTPAPI subprocedure:
   >        rc = http_url_post_xml(
   >
   >     '[11]https://www.myshawtracking.ca:443/otsWebWS/services/OTSWebSvcs'
   >                  : %addr(SOAP) + 2
   >                  : %len(SOAP)
   >                  : *NULL
   >                  : %paddr(Incoming)
   >                  : %addr(rate)
   >                  : HTTP_TIMEOUT
   >                  : HTTP_USERAGENT
   >                  : 'text/xml'
   >                  : '[12]http://www.qualcomm.com/dequeue2');
   >     I am receiving rc = 1 which I believe means that I am
   successfully
   >     receiving an XML response. FYI - The procedure "Incoming" was
   copied
   >     from Scott's EXAMPLE11.
   >     The response XML is as follows.
   >     <soapenv:Body>
   >     <dequeue2Response>
   >     <dequeue2Return>
   >     <count>6</count>
   >     <transactionIdOut>58744654</transactionIdOut>
   >     (transactions>
   >     PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48dHJjaz4=
   >     </transactions>
   >     </dequeue2Return>
   >     </dequeue2Response>
   >     </soapenv:Body>
   >     The "transactions" element is xsd:base64Binary and I don't know
   how to
   >     decode it. I have downloaded Scott's BASE64R4 service program and
   I
   >     suspect I'd use procedure BASE64_DECODE, but I'm not sure how I
   would
   >     employ it in this situation. Also...according to the wiki the
   >     "transactions" element could be as large as "Approximately  1mb"
   >     although I'm not really sure what they mean by approximately??
   >     The "count" and "transactionIdOut" and not encoded and I need the
   data
   >     in them in addition to the encoded data.
   >     I understand that I may not even be using the correct post
   procedure
   >     (remember I'm not that experienced) and in the interim I am going
   to
   >     try some of Scott's other procedures.
   >     Any help or examples on how to get this data would be much
   appreciated.
   >     Thanks!
   >     ___________________________________________________________
   >     Paul Reid
   >     Application Developer III
   >     Erb Group of Companies | 290 Hamilton Road | New Hamburg, Ontario
   | N3A
   >     1A2
   >     Phone: 519.662.6133 ext. 2363
   >     Web: [3][4][13]http://www.erbgroup.com/
   >
   > References
   >
   >     1.
   [5][14]https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSW
   ebSvcs.wsdl
   >     2.
   [6][15]https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Deque
   ue
   >     3. [7][16]http://www.erbgroup.com/
   >
   >
   >
   >
   -----------------------------------------------------------------------
   > This is the FTPAPI mailing list.  To unsubscribe, please go to:
   > [8][17]http://www.scottklement.com/mailman/listinfo/ftpapi
   >
   -----------------------------------------------------------------------
   -----------------------------------------------------------------------
   This is the FTPAPI mailing list.  To unsubscribe, please go to:
   [9][18]http://www.scottklement.com/mailman/listinfo/ftpapi
   -----------------------------------------------------------------------

References

   1. [19]http://www.erbgroup.com/
   2. [20]https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSW
   3. [21]https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Deque
   4. [22]http://www.erbgroup.com/
   5. [23]https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSWeb
Svcs.wsdl
   6. [24]https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Dequeue
   7. [25]http://www.erbgroup.com/
   8. [26]http://www.scottklement.com/mailman/listinfo/ftpapi
   9. [27]http://www.scottklement.com/mailman/listinfo/ftpapi


-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
[28]http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------

References

   1. mailto:PReid@xxxxxxxxxxxx
   2. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs
   3. http://www.qualcomm.com/dequeue2
   4. http://www.erbgroup.com/
   5. mailto:sk@xxxxxxxxxxxxxxxx
   6. mailto:ftpapi@xxxxxxxxxxxxxxxxxxxxxx
   7. mailto:ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx
   8. mailto:PReid@xxxxxxxxxxxx
   9. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/O
  10. https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+De
  11. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs
  12. http://www.qualcomm.com/dequeue2
  13. http://www.erbgroup.com/
  14. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSW
  15. https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Deque
  16. http://www.erbgroup.com/
  17. http://www.scottklement.com/mailman/listinfo/ftpapi
  18. http://www.scottklement.com/mailman/listinfo/ftpapi
  19. http://www.erbgroup.com/
  20. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSW
  21. https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Deque
  22. http://www.erbgroup.com/
  23. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSWebSvcs.wsdl
  24. https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Dequeue
  25. http://www.erbgroup.com/
  26. http://www.scottklement.com/mailman/listinfo/ftpapi
  27. http://www.scottklement.com/mailman/listinfo/ftpapi
  28. 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
-----------------------------------------------------------------------