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

Re: Parsing XML with a value that contains a double quote



Hi Kim,

I've not encountered the problem you describe, so I can only guess...

...do you still have HTTP_XmlReturnPtr(*ON)?  Your prototype seems to 
assume that it's off.  It won't turn off automatically, though... you 
have to call HTTP_XmlReturnPtr(*OFF) to turn it off.  (Or change your 
prototype to get the XML data as a pointer.)

If that's not it, then I'll need you to send me a small but complete 
program that I can copy/paste onto my system to reproduce the problem.

Thanks


On 12/28/2010 11:36 AM, Kim Gibson wrote:
> Hi Scott,
>
> I've made the changes you suggested, and am now successfully writing the whole embedded xml to a temporary file in the IFS. But now when I parse it with http_parse_xml_stmf I get garbage in the "value" field of the "embedded" prototype, and sometimes that garbage contains the word EndElement.
>
> Here are code snippets---
>
>
>       D resp_t          ds                  qualified
>       D                                     based(Template)
>       D transid                       50a   varying
>       D respcode                      30a   varying
>       D respcodetxt                   30a   varying
>
>       D embedded        PR
>       D   resp                              likeds(resp_t)
>       D   depth                       10I 0 value
>       D   name                      1024A   varying const
>       D   path                     24576A   varying const
>       D   value                    32767A   varying const
>       D   attrs                         *   dim(32767)
>       D                                     const options(*varsize)
>
>         // ----------------------------------------------
>          //    Parse the second XML document (the one
>          //    that was embedded)
>          // ----------------------------------------------
>            resp = *allx'00';
>            if (http_parse_xml_stmf( embfile
>                                   : HTTP_XML_CALC
>                                   : *null
>                                   : %paddr(Embedded)
>                                   : %addr(resp) )<  0);
>                unlink(embfile);
>                http_crash();
>            else;
>
>              head = 1;
>              exsr printRequest;
>
>            endif;
>
>
>       P embedded        B
>       D embedded        PI
>       D   resp                              likeds(resp_t)
>       D   depth                       10I 0 value
>       D   name                      1024A   varying const
>       D   path                     24576A   varying const
>       D   value                    32767A   varying const
>       D   attrs                         *   dim(32767)
>       D                                     const options(*varsize)
>
>       D Count           S             10I 0
>       D attrname        s            100a   varying
>       D attrval         s            100a   varying
>
>        /free
>
>           select;
>           when name = 'TransactionID';
>              resp.transid = %trimr(value);
>           when name = 'ResponseCode';
>              resp.respcode  = %trimr(value);
> 	   endsl;
>
> 	P                 E
>
>
> It's frustrating to me that I don't better understand this process. We simply don't have enough experience with API's and RPGLE. Yes, we're in serious need of modernization.
>
> Any ideas??
>
> Thanks so much,
>
> Kim
>
>
>
> From: Kim Gibson
> Sent: Tuesday, December 28, 2010 8:25 AM
> To: 'ftpapi@xxxxxxxxxxxxxxxxxxxxxx'
> Subject: Re: Parsing XML with a value that contains a double quote
>
> Ah, okay thanks. I had put the write into a loop because I thought perhaps I was going to have to retrieve the data in chunks when it exceeded 65535. I'll give this a shot and see if retval.valptr contains the whole huge embedded xml data.
>
> You're right about the XML header-doh.
>
> I'll give this a try this morning. Thanks!
>
> Kim
>
> Date: Mon, 27 Dec 2010 18:13:16 -0600
> From: Scott Klement<sk@xxxxxxxxxxxxxxxx>
> Subject: Re: Parsing XML with a value that contains a double quote
> To: HTTPAPI and FTPAPI Projects<ftpapi@xxxxxxxxxxxxxxxxxxxxxx>
> Message-ID:<4D192B9C.8090707@xxxxxxxxxxxxxxxx>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> Hi Kim,
>
> I wouldn't use the 'WriteToFile' prototype you presented.  Instead, I'd
> use the 'standard' write prototype...  i.e. the one included in the
> IFSIO_H member that's part of HTTPAPI.
>
> Then I'd just do this:
>
>      fd = open(embfile: O_CREAT+O_WRONLY+O_TEXTDATA);
>      callp write(fd: retval.valptr: retval.len);
>      callp close(fd);
>
> There's no need to write an XML header if you're parsing it with Expat.
> (It should already know that the data is XML)  There's also no need to
> call it in a loop, you should have the whole XML document already in
> retval.valptr (unless I'm mistaken?)
>
> The only thing you might consider is translating the data back to ASCII
> when you write it (because HTTPAPI has translated it to EBCDIC for you.)
>
>      fd = open( embfile
>               : O_CREAT + O_WRONLY + O_EXCL +
>                 O_CCSID + O_TEXTDATA + O_TEXT_CREAT
>               : S_IRUSR + S_IWUSR
>               : 819
>               : 0 );
>      callp write(fd: retval.valptr: retval.len);
>      callp close(fd);
>
> That code should cause the open() API to automatically translate the
> data to iso-8859-1 (CCSID 819) when it writes the data to disk.  That
> makes it easier when you want to open the file with Notepad or a browser
> (for debugging) and means that Expat has to jump through fewer hoops
> (since it doesn't understand EBCDIC directly, but does understand ASCII.)
>
>
> On 12/27/2010 5:43 PM, Kim Gibson wrote:
>>
>>       Hello again,
>>
>>
>>       I'm using a pointer to read the large amount of data being returned in
>>       the http_url_post_xml response. I know how to use a pointer to read
>>       data coming in from a file in the IFS, but what about data that simply
>>       resides in memory? I'm sure I'm just missing something very elementary
>>       here.
>>
>>
>>       Here are relevant snippets of my code:
>>
>>
>>       I've got a data structure that contains a pointer and a length:
>>
>>
>>            D value_t         ds                  qualified
>>
>>            D   valptr                        *
>>
>>            D   len                         10i 0
>>
>>
>>       I've altered my EndOfElement prototype definition to include the data
>>       structure:
>>
>>
>>            D EndOfElement    PR
>>
>>            D   UserData                      *   value
>>
>>            D   depth                       10I 0 value
>>
>>            D   name                      1024A   varying const
>>
>>            D   path                     24576A   varying const
>>
>>            D   retval                            likeds(value_t)
>>
>>            D   attrs                         *   dim(32767)
>>
>>            D                                     const options(*varsize)
>>
>>
>>
>>       I'm using http_XmlReturnPtr:
>>
>>
>>         http_XmlReturnPtr(*ON);
>>
>>
>>
>>       My call to the web service looks like this:
>>
>>
>>             rc = http_url_post_xml(
>>
>>                 'https://someurl.com/services/eoservice.asmx'
>>
>>                       : %addr(SOAP)+2
>>
>>                       : %len(SOAP)
>>
>>                       : %paddr(StartOfElement)
>>
>>                       : %paddr(EndOfElement)
>>
>>                       : *NULL );
>>
>>
>>
>>
>>       The return tag "DeliverExamOneContentResult" contains all the
>>       unescaped data that I want to write to a temporary file in the IFS, so
>>       I can read it back in and parse it with http_parse_xml_stmf.
>>
>>
>>            P EndOfElement    B
>>
>>            D EndOfElement    PI
>>
>>            D   UserData                      *   value
>>
>>            D   depth                       10I 0 value
>>
>>            D   name                      1024A   varying const
>>
>>            D   path                     24576A   varying const
>>
>>            D   retval                            likeds(value_t)
>>
>>            D   attrs                         *   dim(32767)
>>
>>            D                                     const options(*varsize)
>>
>>
>>            D writeToFile     PR            10I 0 ExtProc('write')
>>
>>            D  fildes                       10i 0 value
>>
>>            D  buf                       65535A   const options(*varsize)
>>
>>            D  bytes                        10U 0 value
>>
>>
>>            D xmlhdr          s             80a   varying
>>
>>            D fd              s             10i 0
>>
>>
>>             /free
>>
>>
>>                  if (%trim(name)<>   'DeliverExamOneContentResult');
>>
>>                    return;
>>
>>                  endif;
>>
>>
>>                  // ------------------------------------------
>>
>>                  //   create new stream file in IFS
>>
>>                  // ------------------------------------------
>>
>>
>>                  embfile = http_tempfile();
>>
>>
>>                  // ------------------------------------------
>>
>>                  //    Open stream file for appending data
>>
>>                  //    and write embedded XML document to it
>>
>>                  // ------------------------------------------
>>
>>
>>                  fd = open(embfile: O_WRONLY+O_TEXTDATA);
>>
>>
>>                  xmlhdr= '<?xml version="1.0"?>' + x'0d25';
>>
>>                  writeToFile(fd: xmlhdr: %len(xmlhdr));
>>
>>
>>            // here's where the problem is - how to I retrieve the data from
>>       memory?
>>
>>            // Whenever I use %addr(retval.valptr), I get a compile error:
>>
>>            // The type of the parameter specified for the call does not
>>       match the prototype.
>>
>>
>>                  dow writeToFile(fd: %addr(retval.valptr) : retval.len)>=0;
>>
>>                    writeToFile(fd: %addr(retval.valptr) : retval.len);
>>
>>                  enddo;
>>
>>
>>                  callp close(fd);
>>
>>
>>
>>               //endsl;
>>
>>
>>             /end-free
>>
>>            P                 E
>>
>>
>>       I see that retval.valptr is a pointer and parameter buf in writeToFile
>>       is a character field---how do I return the data at pointer
>>       retval.valptr? What am I missing?
>>
>>
>>       Thanks for your help--again!
>>
>>
>>       Kim Gibson
>
>
> -----------------------------------------------------------------------
> 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
-----------------------------------------------------------------------