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

Re: XML Parse failed at line 38, col 2: mismatch tag



Sender: Scott Klement <sk@xxxxxxxxxxxxxxxx>


Hi Peter,


The SOAP request in the message you posted doesn't match the WDSL document that you reference. Also, the URL you included in your code isn't the one listed in the WSDL document -- so I'm not sure where you got these from? At any rate, what appears to be happening in your code is that you're getting back an HTML document that tells you that the URL you provided doesn't exist. Then, HTTPAPI's XML parser is trying to parse that HTML document as if it were XML, and that's why you get the XML Parse error.

I've modified your program to use the SOAP request the way the WDSL document specifies it. There are still some problems, and I'll say more about that in a minute, but here's the code:

H DFTACTGRP(*NO) BNDDIR('HTTPAPI':'QC2LE')

     D ExchRateX       PR                  ExtPgm('EXCHRATEX')
     D  Country1                      3A   const

     D ExchRateX       PI
     D  Country1                      3A   const

/copy httpapi_h

     D Incoming        PR
     D   rate                     32767A   varying
     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 Soap            s          32767A   varying
     D rc              s             10I 0
     D rate            s          32767A   varying

/free

         http_debug(*ON);
         rate='';

        SOAP =
         '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>'
        +'<SOAP-ENV:Envelope'
        +'    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";'
        +'    xmlns:xsd="http://www.w3.org/2001/XMLSchema";'
        +'    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; >'
        +'<SOAP-ENV:Body>'
        +'  <mns:getLatestNoonRate'
        +'       xmlns:mns="http://v1_0.WebService.fxrates.markets";'
        +'       SOAP-ENV:encodingStyle='
        +              '"http://schemas.xmlsoap.org/soap/encoding/";>'
        +'    <currency_code xsi:type="xsd:string">'
        +         %trim(Country1)
        +    '</currency_code>'
        +'  </mns:getLatestNoonRate>'
        +'</SOAP-ENV:Body>'
        +'</SOAP-ENV:Envelope>';

rc = http_url_post_xml(

'http://www.newyorkfed.org/markets/fxrates/WebService/v1_0/FXWS.cfc'
                        : %addr(SOAP) + 2
                        : %len(SOAP)
                        : *NULL
                        : %paddr(Incoming)
                        : %addr(rate)
                        : HTTP_TIMEOUT
                        : HTTP_USERAGENT
                        : 'text/xml'
                        : *blanks );


if (rc <> 1); http_crash(); else; http_comp(%trim(Country1) + ' ' + Rate); endif;

*inlr = *on;

/end-free



     P Incoming        B
     D Incoming        PI
     D   rate                     32767A   varying
     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 atof            PR            12A   extproc('atof')
     D   string                        *   value options(*string)

/free

          if (name = 'ns1:getLatestNoonRateReturn');
             rate += value;
          endif;

      /end-free
     P                 E

This code works, sort of. The problem is, this Web Service doesn't return a field containing an exchange rate. Instead, it embeds yet another XML document inside the SOAP message that it returns.

So, when the http_url_post_xml() routine is complete, you'll have an XML document in the "Rate" variable instead of an actual rate. You'd then have to feed "Rate" into an XML parser to actually get the exchange rate from it!

To get a better idea of what I'm talking about, replace the http_url_post_xml() with the following call to HTTPAPI:

rc = http_url_post(

'http://www.newyorkfed.org/markets/fxrates/WebService/v1_0/FXWS.cfc'
                        : %addr(SOAP) + 2
                        : %len(SOAP)
                        : '/tmp/nyfed.xml'
                        : HTTP_TIMEOUT
                        : HTTP_USERAGENT
                        : 'text/xml'
                        : *blanks );

What this does is download the response from the web server and store it into a file (as opposed to parsing the XML and returning each element individually).

As you'll see if you examine that nyfed.xml file, there's an XML document inside another XML document! The data stored inside the <getLatestNoonRateReturn> XML element is actually another document, with all of it's XML tags escaped so that the XML parser will tread it as data instead of treating it as additional XML tags.

So you'd have to save that data to a file as an XML document, and parse that "document-within-a-document" again to get the actual elements. Though, you could also "cheat" and use %SCAN/%SUBST to get the actual rate from the inner document. For example:

H DFTACTGRP(*NO) BNDDIR('HTTPAPI':'QC2LE')

     D ExchRateX       PR                  ExtPgm('EXCHRATEX')
     D  Country1                      3A   const

     D ExchRateX       PI
     D  Country1                      3A   const

/copy httpapi_h

     D Incoming        PR
     D   rate                     32767A   varying
     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 Soap            s          32767A   varying
     D rc              s             10I 0
     D rate            s          32767A   varying
     D pos             s             10I 0
     D len             s             10I 0

/free

         http_debug(*ON);
         rate='';

        SOAP =
         '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>'
        +'<SOAP-ENV:Envelope'
        +'    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";'
        +'    xmlns:xsd="http://www.w3.org/2001/XMLSchema";'
        +'    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; >'
        +'<SOAP-ENV:Body>'
        +'  <mns:getLatestNoonRate'
        +'       xmlns:mns="http://v1_0.WebService.fxrates.markets";'
        +'       SOAP-ENV:encodingStyle='
        +              '"http://schemas.xmlsoap.org/soap/encoding/";>'
        +'    <currency_code xsi:type="xsd:string">'
        +         %trim(Country1)
        +    '</currency_code>'
        +'  </mns:getLatestNoonRate>'
        +'</SOAP-ENV:Body>'
        +'</SOAP-ENV:Envelope>';

      /undefine DEBUG
      /if defined(DEBUG)
        rc = http_url_post(

'http://www.newyorkfed.org/markets/fxrates/WebService/v1_0/FXWS.cfc'
                        : %addr(SOAP) + 2
                        : %len(SOAP)
                        : '/tmp/nysetest.xml'
                        : HTTP_TIMEOUT
                        : HTTP_USERAGENT
                        : 'text/xml'
                        : *blanks );

      /else
        rc = http_url_post_xml(

'http://www.newyorkfed.org/markets/fxrates/WebService/v1_0/FXWS.cfc'
                        : %addr(SOAP) + 2
                        : %len(SOAP)
                        : *NULL
                        : %paddr(Incoming)
                        : %addr(rate)
                        : HTTP_TIMEOUT
                        : HTTP_USERAGENT
                        : 'text/xml'
                        : *blanks );
      /endif



       if (rc <> 1);
          http_crash();
       endif;

       pos = %scan('<frbny:OBS_VALUE>': Rate);
       if (pos > 0);
          pos = %scan('>': Rate: Pos) + 1;
          len = %scan('</frbny:OBS_VALUE': Rate: Pos) - pos;
       endif;
       if (pos>1 and len>0);
          Rate = %subst(Rate: pos: len);
          http_comp(%trim(Country1) + ' ' + Rate);
       endif;

*inlr = *on;

/end-free



     P Incoming        B
     D Incoming        PI
     D   rate                     32767A   varying
     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 atof            PR            12A   extproc('atof')
     D   string                        *   value options(*string)

/free

          if (name = 'ns1:getLatestNoonRateReturn');
             rate += value;
          endif;

      /end-free
     P                 E

Hope that helps...

---
Scott Klement  http://www.scottklement.com

On Thu, 22 Jun 2006, Hoey, Peter wrote:

Hello,



           I am trying to utilize the new exchange rate Web Service
offered by the Federal Reserve Bank of New York

(see http://www.ny.frb.org/markets/pilotfx.html ). I was hoping to use
the HTTP API's to retrieve the exchange rate. There is a link on the web
site that will provide the Web Service Definition. There is a lot of
wsdl code that they show. I tried to extract what I needed for the SOAP
message that the HTTP API's need. I believe the exchange rate that is
returned is a string variable as opposed to the floating point variable
that are returned in some of your examples.  Thanks in advance for any
help.

.

Here is the code that I wrote:



H DFTACTGRP(*NO) BNDDIR('HTTPAPI':'QC2LE')



D ExchRateX PR ExtPgm('EXCHRATEX')

D Country1 3A const



D ExchRateX PI

D Country1 3A const



/copy httpapi_h



D Incoming PR

D rate 12A

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 Soap s 32767A varying

D rc s 10I 0

D rate s 12A



/free

SOAP =

'<?xml version="1.0" encoding="US-ASCII" standalone="no"?>'

+'<SOAP-ENV:Envelope'

+' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";'

+' xmlns:tns="http://www.newyorkfed.org./markets/fxrates/WebService/";

+'<SOAP-ENV:Body>'

+' <tns:getLatestNoonRateRequest>'

+' <tns:currency_code>'+ %trim(Country1) +'</tns:currency_code>'

+' </tns:getLatestNoonRateRequest>'

+'</SOAP-ENV:Body>'

+'</SOAP-ENV:Envelope>';



rc = http_url_post_xml(

'http://www.newyorkfed.org./markets/fxrates/WebService/v1_0/FXWS'

: %addr(SOAP) + 2

: %len(SOAP)

: *NULL

: %paddr(Incoming)

: %addr(rate)

: HTTP_TIMEOUT

: HTTP_USERAGENT

: 'text/xml'

: *blanks );



if (rc <> 1);

http_crash();

else;

http_comp(%trim(Country1) + ' ' + Rate);

endif;



*inlr = *on;



/end-free



P Incoming B

D Incoming PI

D rate 12A

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 atof PR 12A extproc('atof')

D string * value options(*string)



/free

if (name = 'getLatestNoonRateReturn');

rate = atof(value);

endif;

/end-free

P E






Regards,


Peter W. Hoey






-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubsribe from the list send mail
to majordomo@xxxxxxxxxxxxx with the body: unsubscribe ftpapi mymailaddr
-----------------------------------------------------------------------