[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 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: [1]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][2]https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/O
TSW
> ebSvcs.wsdl
> The WIKI for this Web Service is:
>
[2][3]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(
>
> '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][4]http://www.erbgroup.com/
>
> References
>
> 1.
[5]https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSW
ebSvcs.wsdl
> 2.
[6]https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Deque
ue
> 3. [7]http://www.erbgroup.com/
>
>
>
>
-----------------------------------------------------------------------
> This is the FTPAPI mailing list. To unsubscribe, please go to:
> [8]http://www.scottklement.com/mailman/listinfo/ftpapi
>
-----------------------------------------------------------------------
-----------------------------------------------------------------------
This is the FTPAPI mailing list. To unsubscribe, please go to:
[9]http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------
References
1. http://www.erbgroup.com/
2. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSW
3. https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Deque
4. http://www.erbgroup.com/
5. https://www.myshawtracking.ca/otsWebWS/services/OTSWebSvcs/wsdl/OTSWebSvcs.wsdl
6. https://intinfo.myqualcomm.com/display/iWebInt/ESS+High-Volume+Dequeue
7. http://www.erbgroup.com/
8. http://www.scottklement.com/mailman/listinfo/ftpapi
9. 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
-----------------------------------------------------------------------