[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.
You look to be on the right path. I am not sure why you are having problems with count and transactionIdOut. To get started, just define them as character fields. Does that work?
Good. Now you just need to convert to numbers.
Monitor;
Count = %dec(%trim(countChar):5:0); // should work - probably shouldn't need the %trim but never hurts
On-error;
Dsply countChar;
End-mon;
As for resultVar. Write it to the IFS. The prototypes for writing to the IFS are already included in HTTPAPI so you can use them to do the lifting. If you haven't written to the IFS, this article is one of the short and sweet versions. http://iprodeveloper.com/rpg-programming/writing-delimited-file-ifs-hard-way Actually, maybe EXAMPLE17 is even easier. See SaveEmbed procedure.
Once written to the IFS, HTTPAPI with Expat can be used to parse the stream file. See http_parse_xml_stmf
-----Original Message-----
From: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx [mailto:ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of PReid@xxxxxxxxxxxx
Sent: Monday, December 16, 2013 3:33 PM
To: HTTPAPI and FTPAPI Projects
Subject: Re: Advice on how to process xsd:base64Binary XML element retrieved from a web service.
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(
'https://www.myshawtracking.ca:443/otsWebWS/services/OTSWebSvcs'
: %addr(SOAP) + 2
: %len(SOAP)
: *NULL
: %paddr(Incoming)
: %addr(rate)
: HTTP_TIMEOUT
: HTTP_USERAGENT
: 'text/xml'
: '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: http://www.erbgroup.com/
From: Scott Klement <sk@xxxxxxxxxxxxxxxx>
To: HTTPAPI and FTPAPI Projects <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: 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, 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]
https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSW
> ebSvcs.wsdl
> The WIKI for this Web Service is:
> [2]
https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Deque
> 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(
>
> 'https://www.myshawtracking.ca:443/otsWebWS/services/OTSWebSvcs'
> : %addr(SOAP) + 2
> : %len(SOAP)
> : *NULL
> : %paddr(Incoming)
> : %addr(rate)
> : HTTP_TIMEOUT
> : HTTP_USERAGENT
> : 'text/xml'
> : '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]http://www.erbgroup.com/
>
> References
>
> 1.
https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSWebSvcs.wsdl
> 2.
https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Dequeue
> 3. http://www.erbgroup.com/
>
>
>
> -----------------------------------------------------------------------
> 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
-----------------------------------------------------------------------
-----------------------------------------------------------------------
This is the FTPAPI mailing list. To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------