soap y dato de retorno

Post Reply
User avatar
carlos vargas
Posts: 1421
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua

soap y dato de retorno

Post by carlos vargas »

Estimados, tengo un problema
Esta web, me permite recuperar el tipo de cambio del dia, y del mes.
usando soap, con vfp, ambos funcionan de perlas, pero con harbour, solo puedo recuperar el del dia.
https://servicios.bcn.gob.ni/Tc_Servici ... cioTC.asmx

el del mes, no lo puedo recuperara, parece que ese metodo retorna un xml con los datos, y el ole de harbour no lo reconoce.
algien que me pueda echar una mano.

Code: Select all

   LOCAL oSoap
   LOCAL aTableTC := {}, nValue
   LOCAL dDateIni, dDateEnd

   dDateIni := DMY2DATE( 1, nMonth, nYear )
   dDateEnd := EoM( dDateIni )

   WaitOn( "Recuperando tipo de cambio del mes de " + CMonth( dDateIni ) + " del año " + HB_NToS( nYear ) )
   CursorWait()

   IF ( oSoap := win_oleCreateObject( "MSSOAP.SoapClient30" ) ) != NIL
      oSoap:MSSoapInit( "https://servicios.bcn.gob.ni/Tc_Servicio/ServicioTC.asmx?WSDL" )
      FOR x := dDateIni TO dDateEnd
         nValue := oSoap:RecuperaTC_Dia( nYear, nMonth, Day( x ) )
         IF nValue > 0
            AAdd( aTableTC, { x, nValue } )
         ENDIF
      NEXT
   ELSE
      MsgAlert( "Error: SOAP Toolkit 3.0 not available." + FINL + win_oleErrorText() )
   ENDIF

   WaitOff()

   oSoap := NIL

   hb_gcAll( TRUE )

RETURN aTableTC
#pragma BEGINDUMP

/*definición de constante necesaria para compilador XCC*/
#ifdef __XCC__
   #define WINVER 5
#endif

/*llamada a encabezados de api de xharbour y windows SDK*/
#include "hbapi.h"
#include "hbapiitm.h"
#include "hbapierr.h"
#include "hbdate.h"

#include "shlobj.h"
#include "windows.h"

HB_FUNC( DMY2DATE )
{
   int iDay   = hb_parni( 1 );
   int iMonth = hb_parni( 2 );
   int iYear  = hb_parni( 3 );

   hb_retd( iYear, iMonth, iDay );
}

#pragma ENDDUMP
 
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: soap y dato de retorno

Post by nageswaragunupudi »

Mr Carlos

Please try this approach:

Code: Select all

// soap test
//
#include "fivewin.ch"

static cURL          := "https://servicios.bcn.gob.ni/Tc_Servicio/ServicioTC.asmx?op=RecuperaTC_Dia"
static cHost         := "servicios.bcn.gob.ni"
static cSoapAction   := "http://servicios.bcn.gob.ni/RecuperaTC_Dia"

static oHttp

//----------------------------------------------------------------------------//

function Main()

   local d, d1, d2
   local aRates   := {}

   SET DATE ITALIAN
   SET CENTURY ON

   TRY
      oHttp := CreateObject( 'MSXML2.XMLHTTP' )
   CATCH
      oHttp := CreateObject( 'Microsoft.XMLHTTP' )
   END

   if oHttp == nil
      ? "Fail"
      return nil
   endif

   msgRun("Reading Exchange Rates","PLEASE WAIT", ;
        {|| aRates := ReadRates( {^ 2017/09/01 } ) } )

   XBROWSER aRates TITLE "EXCHANGE RATES"

return nil

//----------------------------------------------------------------------------//

static function ReadRates( dDate )

   local d, d2 := EOM( dDate )
   local aRates   := {}

   for d := dDate to d2
      AAdd( aRates, { d, SendHttpRequest( makeSoapRequest( d ) ) } )
   next

return aRates

//----------------------------------------------------------------------------//

static function MakeSoapRequest( dDate )

local cXml

TEXT INTO cXml
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <RecuperaTC_Dia xmlns="http://servicios.bcn.gob.ni/">
      <Ano>YEAR</Ano>
      <Mes>MONTH</Mes>
      <Dia>DAY</Dia>
    </RecuperaTC_Dia>
  </soap:Body>
</soap:Envelope>
ENDTEXT

   cXml     := StrTran( cXml, "YEAR",  cValToChar( YEAR( dDate ) ) )
   cXml     := StrTran( cXml, "MONTH", cValToChar( MONTH( dDate ) ) )
   cXml     := StrTran( cXml, "DAY",   cValToChar( DAY( dDate ) ) )

return cXml

//----------------------------------------------------------------------------//

static function SendHttpRequest( cRequestXML )

   local cContentType   := "text/xml; charset=utf-8"
   local cUserAgent     := "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
   local cXml           := cRequestXML
   //
   local cResponseBody, nStatus, cStatusText
   local nResult        := 0

   oHttp:Open( 'POST', cUrl, .F. ) //, "61420255" )

   oHttp:SetRequestHeader( "Connection:", "Keep-Alive" )
   oHttp:SetRequestHeader( "Host",           cHost )
   oHttp:SetRequestHeader( "SOAPAction",     cSOAPAction )
   oHttp:setRequestHeader( "User-Agent",     cUserAgent )
   oHttp:SetRequestHeader( "Content-Type",   cContentType )
   oHttp:SetRequestHeader( "Content-Length", LTrim( Str( Len( cXml ) ) ) )

   TRY
      oHttp:Send( cXml )
      SysRefresh()
   CATCH
      MsgInfo("Could not send the XML documnent." +CRLF+ "The reason could be either the internet connection failed or its a server problem")
      QUIT
   END

   cResponseBody := oHttp:ResponseBody

   oHttp:getAllResponseHeaders()
   nStatus       := oHttp:Status
   cStatusText   := oHttp:StatusText

   if nStatus == 200
      nResult  := ReadResult( cResponseBody )
   endif

return nResult

//----------------------------------------------------------------------------//

static function ReadResult( cXml )

return Val( BeforAtNum( "</RecuperaTC_DiaResult>", AfterAtNum( "<RecuperaTC_DiaResult>", cXml, 1 ), 1 ) )

//----------------------------------------------------------------------------//
 
Result:
Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
carlos vargas
Posts: 1421
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua

Re: soap y dato de retorno

Post by carlos vargas »

Excellent Mr. Rao.

It is possible to use the method RecuperaTC_Mes ?, this allows to obtain the data of the whole month in a single call. but I could not get the data, I get an empty object.

although the objective of obtaining the data has already been fulfilled.

Getting the data from RecuperaTC_Mes is a curiosity.

very grateful for the help.
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: soap y dato de retorno

Post by nageswaragunupudi »

Microsoft SOAP toolkit 3.0 was deprecated by Microsoft almost ten years back. This can not even be downloaded officially from Microsoft. We can download from 3rd party sites and install but not recommended. I am also not sure which of the present OS supports this toolkit. Net framework provides an improved library for this but not available for our use.

This is now history and not good for present and future use. Even with that toolkit we need to loop for each date. That is clear from the soap documentation for this application on their web-site.
Regards

G. N. Rao.
Hyderabad, India
User avatar
carlos vargas
Posts: 1421
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua

Re: soap y dato de retorno

Post by carlos vargas »

Rao, thank you,
you test with to call to RecuperaTC_Mes :-), export to xml file.
now, the next pass is export xml file to hash or array.

salu2
carlos vargas
Image

Code: Select all

/ soap test 2
// 
#include "fivewin.ch"

static cHost        := "servicios.bcn.gob.ni"
static cURL1        := "https://servicios.bcn.gob.ni/Tc_Servicio/ServicioTC.asmx?op=RecuperaTC_Dia"
static cURL2        := "https://servicios.bcn.gob.ni/Tc_Servicio/ServicioTC.asmx?op=RecuperaTC_Mes"
static cSoapAction1 := "http://servicios.bcn.gob.ni/RecuperaTC_Dia"
static cSoapAction2 := "http://servicios.bcn.gob.ni/RecuperaTC_Mes"
static oHttp

//----------------------------------------------------------------------------//

function Main()
    local aRates := {}

    SET DATE ITALIAN
    SET CENTURY ON

    TRY
        oHttp := CreateObject( 'MSXML2.XMLHTTP' )
    CATCH
        oHttp := CreateObject( 'Microsoft.XMLHTTP' )
    END

    if oHttp == nil
        ? "Fail"
        return nil
    endif

    msgRun( "Reading Exchange Rates 1","PLEASE WAIT", {|| aRates := ReadRates1( {^ 2017/09/01 } ) } )

    XBROWSER aRates TITLE "EXCHANGE RATES"

    msgRun( "Reading Exchange Rates 2","PLEASE WAIT", {|| ReadRates2( 10, 2017 ) } )
   
return nil

//----------------------------------------------------------------------------//

static function ReadRates1( dDate )
    local d, d2 := EOM( dDate )
    local aRates := {}

    for d := dDate to d2
        AAdd( aRates, { d, SendHttpRequest1( makeSoapRequest1( d ) ) } )
    next

return aRates

//----------------------------------------------------------------------------//

static procedure ReadRates2( nMonth, nYear )
    local cRates := ""

    cRates := SendHttpRequest2( makeSoapRequest2( nMonth, nYear ) )
   
    if SavedResult( cRates )
        ?"save xml file with rates"
    endif
   
return

//----------------------------------------------------------------------------//

static function MakeSoapRequest1( dDate )
    local cXml

    TEXT INTO cXml
        <?xml version="1.0" encoding="utf-8"?>
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
          <soap:Body>
            <RecuperaTC_Dia xmlns="http://servicios.bcn.gob.ni/">
              <Ano>YEAR</Ano>
              <Mes>MONTH</Mes>
              <Dia>DAY</Dia>
            </RecuperaTC_Dia>
          </soap:Body>
        </soap:Envelope>
    ENDTEXT
    
    cXml := StrTran( cXml, chr(9), "" )
    cXml := StrTran( cXml, "YEAR",  cValToChar( YEAR( dDate ) ) )
    cXml := StrTran( cXml, "MONTH", cValToChar( MONTH( dDate ) ) )
    cXml := StrTran( cXml, "DAY",   cValToChar( DAY( dDate ) ) )

return cXml

//----------------------------------------------------------------------------//

static function MakeSoapRequest2( nMonth, nYear )
    local cXml

    TEXT INTO cXml
        <?xml version="1.0" encoding="utf-8"?>
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
          <soap:Body>
            <RecuperaTC_Mes xmlns="http://servicios.bcn.gob.ni/">
              <Ano>YEAR</Ano>
              <Mes>MONTH</Mes>
            </RecuperaTC_Mes>
          </soap:Body>
        </soap:Envelope>
    ENDTEXT
    
    cXml := StrTran( cXml, chr(9), "" )
    cXml := StrTran( cXml, "YEAR",  cValToChar( nYear  ) )
    cXml := StrTran( cXml, "MONTH", cValToChar( nMonth ) )

return cXml

//----------------------------------------------------------------------------//

static function SendHttpRequest1( cRequestXML )
    local cContentType   := "text/xml; charset=utf-8"
    local cUserAgent     := "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    local cXml           := cRequestXML
    //
    local cResponseBody, nStatus, cStatusText
    local nResult        := 0

    oHttp:Open( 'POST', cURL1, .F. )

    oHttp:SetRequestHeader( "Connection:",    "Keep-Alive" )
    oHttp:SetRequestHeader( "Host",           cHost )
    oHttp:SetRequestHeader( "SOAPAction",     cSOAPAction1 )
    oHttp:setRequestHeader( "User-Agent",     cUserAgent )
    oHttp:SetRequestHeader( "Content-Type",   cContentType )
    oHttp:SetRequestHeader( "Content-Length", LTrim( Str( Len( cXml ) ) ) )

    TRY
        oHttp:Send( cXml )
        SysRefresh()
    CATCH
        MsgInfo("Could not send the XML documnent." +CRLF+ "The reason could be either the internet connection failed or its a server problem")
        QUIT
    END

    cResponseBody := oHttp:ResponseBody

    oHttp:getAllResponseHeaders()
    nStatus     := oHttp:Status
    cStatusText := oHttp:StatusText

    if nStatus == 200
        nResult := ReadResult( cResponseBody )
    endif

return nResult

//----------------------------------------------------------------------------//

static function SendHttpRequest2( cRequestXML )
    local cContentType   := "text/xml; charset=utf-8"
    local cUserAgent     := "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    local cXml           := cRequestXML
    //
    local cResponseBody, nStatus, cStatusText
    local cResult        := ""

    oHttp:Open( 'POST', cURL2, .F. )

    oHttp:SetRequestHeader( "Connection:",    "Keep-Alive" )
    oHttp:SetRequestHeader( "Host",           cHost )
    oHttp:SetRequestHeader( "SOAPAction",     cSOAPAction2 )
    oHttp:setRequestHeader( "User-Agent",     cUserAgent )
    oHttp:SetRequestHeader( "Content-Type",   cContentType )
    oHttp:SetRequestHeader( "Content-Length", LTrim( Str( Len( cXml ) ) ) )

    TRY
        oHttp:Send( cXml )
        SysRefresh()
    CATCH
        MsgInfo("Could not send the XML documnent." +CRLF+ "The reason could be either the internet connection failed or its a server problem")
        QUIT
    END

    cResponseBody := oHttp:ResponseBody

    oHttp:getAllResponseHeaders()
    nStatus       := oHttp:Status
    cStatusText   := oHttp:StatusText

    if nStatus == 200
        cResult  := cResponseBody
    endif

return cResult

//----------------------------------------------------------------------------//

static function ReadResult( cXml )

return Val( BeforAtNum( "</RecuperaTC_DiaResult>", AfterAtNum( "<RecuperaTC_DiaResult>", cXml, 1 ), 1 ) )

//----------------------------------------------------------------------------//

static function SavedResult( cXml )
    ?cXml
return ( StrFile( cXml, "tc.xml" ) > 0 )
 
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: soap y dato de retorno

Post by nageswaragunupudi »

You are right Mr Carlos. I am sorry, I did not understand your post correctly and also did not notice the existence of the operation "RecuperaTC_Mes". Yes, in one call we get all the rates for the month. Parsing return xml is a simpler matter.

But today when I tested, the site is not working properly and it is returning blank results.

Code: Select all

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><RecuperaTC_DiaResponse xmlns="http://servicios.bcn.gob.ni/"><RecuperaTC_DiaResult>0</RecuperaTC_DiaResult></RecuperaTC_DiaResponse></soap:Body></soap:Envelope>
Day's rate returned is 0.

Code: Select all

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><RecuperaTC_MesResponse xmlns="http://servicios.bcn.gob.ni/" /></soap:Body></soap:Envelope>
Rates xml is blank.

There is no problem with our program which worked yesterday.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: soap y dato de retorno

Post by nageswaragunupudi »

The site is working again now. As you said, using the operation "RecuperaTC_Mes" is very fast.

Code: Select all

// soap test
//
#include "fivewin.ch"

#ifdef __XHARBOUR__
   #xtranslate HB_At( <p>, <c>, [<f>] [,<n>] ) => At( <p>, <c>, [<f>] [,<n>])
#endif

static cURL          := "https://servicios.bcn.gob.ni/Tc_Servicio/ServicioTC.asmx?op=RecuperaTC_Mes"
static cHost         := "servicios.bcn.gob.ni"
static cSoapAction   := "http://servicios.bcn.gob.ni/RecuperaTC_Mes"

static oHttp

//----------------------------------------------------------------------------//

function Main()

   local d, d1, d2
   local aRates   := {}

   SET DATE ITALIAN
   SET CENTURY ON

   TRY
      oHttp := CreateObject( 'MSXML2.XMLHTTP' )
   CATCH
      oHttp := CreateObject( 'Microsoft.XMLHTTP' )
   END

   if oHttp == nil
      ? "Fail"
      return nil
   endif

   msgRun("Reading Exchange Rates","PLEASE WAIT", ;
        {|| aRates := ReadRates( {^ 2017/08/01 } ) } )

   XBROWSER aRates TITLE "EXCHANGE RATES"

return nil

//----------------------------------------------------------------------------//

static function ReadRates( dDate )

return SendHttpRequest( makeSoapRequest( dDate ) )

//----------------------------------------------------------------------------//

static function MakeSoapRequest( dDate )

local cXml

TEXT INTO cXml
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <RecuperaTC_Mes xmlns="http://servicios.bcn.gob.ni/">
      <Ano>YEAR</Ano>
      <Mes>MONTH</Mes>
    </RecuperaTC_Mes>
  </soap:Body>
</soap:Envelope>
ENDTEXT

   cXml     := StrTran( cXml, "YEAR",  cValToChar( YEAR( dDate ) ) )
   cXml     := StrTran( cXml, "MONTH", cValToChar( MONTH( dDate ) ) )

return cXml

//----------------------------------------------------------------------------//

static function SendHttpRequest( cRequestXML )

   local cContentType   := "text/xml; charset=utf-8"
   local cUserAgent     := "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
   local cXml           := cRequestXML
   //
   local cResponseBody, nStatus, cStatusText
   local aResult        := {}

   oHttp:Open( 'POST', cUrl, .F. )

   oHttp:SetRequestHeader( "Connection:", "Keep-Alive" )
   oHttp:SetRequestHeader( "Host",           cHost )
   oHttp:SetRequestHeader( "SOAPAction",     cSOAPAction )
   oHttp:setRequestHeader( "User-Agent",     cUserAgent )
   oHttp:SetRequestHeader( "Content-Type",   cContentType )
   oHttp:SetRequestHeader( "Content-Length", LTrim( Str( Len( cXml ) ) ) )

   TRY
      oHttp:Send( cXml )
      SysRefresh()
   CATCH
      MsgInfo("Could not send the XML documnent." +CRLF+ "The reason could be either the internet connection failed or its a server problem")
      QUIT
   END

   cResponseBody := oHttp:ResponseBody

   oHttp:getAllResponseHeaders()
   nStatus       := oHttp:Status
   cStatusText   := oHttp:StatusText

   if nStatus == 200
      aResult  := ReadResults( cResponseBody )
   else
      ? nStatus
      PostQuitMessage( 0 )
      QUIT
   endif

return aResult

//----------------------------------------------------------------------------//

static function ReadResults( cXml )

   local aRates   := {}
   local d, n, nAt, nFrom   := 1

   // There are many ways to extract data from xml
   // This is fast and has no overhead of calling other classes

   do while ( nAt := HB_At( "<Fecha>", cXml, nFrom ) ) > 0
      nFrom    := nAt + 7
      nAt      := HB_At( "</Fecha>", cXml, nFrom )
      d        := SubStr( cXml, nFrom, nAt - nFrom ) //Left( cXml, nAt - 1 )
      nAt      := HB_At( "<Valor>", cXml, nFrom )
      nFrom    := nAt + 7
      nAt      := HB_At( "</Valor>", cXml, nFrom )
      n        := SubStr( cXml, nFrom, nAt - nFrom )
      AAdd( aRates, { STOD( StrTran( d, "-", "" ) ), Val( n ) } )
   enddo

   ASort( aRates,,,{ |x,y| x[ 1 ] < y[ 1 ] } )

return aRates

//----------------------------------------------------------------------------//
 
Image
Regards

G. N. Rao.
Hyderabad, India
horacio
Posts: 1270
Joined: Wed Jun 21, 2006 12:39 am
Location: Capital Federal Argentina

Re: soap y dato de retorno

Post by horacio »

since that version found this function SendHttpRequest? Because I get an error compiling the example. Thank you

Saludos
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: soap y dato de retorno

Post by nageswaragunupudi »

The function "SendHttpRequest" is included in the program itself.
Please let us know what is the compilation error you are getting.

If you are building with xHarbour you get unresolved external error HB_AT. I just modified the program to include a translation for HB_AT. Please copy the revised program.

You can now build it with xHarbour also. This program should work with earlier versions of FWH also.

I tested successfully with bcc7 + Harbour and xHarbour, MSVC32, MSVC64 and borland64. This program compiles and works correctly with all compilers.
Regards

G. N. Rao.
Hyderabad, India
User avatar
carlos vargas
Posts: 1421
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua

Re: soap y dato de retorno

Post by carlos vargas »

Rao, thansk.

all work ok. :-)

salu2
carlos vargas
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
VitalJavier
Posts: 188
Joined: Mon Jun 10, 2013 6:40 pm

Re: soap y dato de retorno

Post by VitalJavier »

Saldos compañeros
Alguien ya lo ha echo para Mexico
Necesito obtener el tipo de cambio
D.Fernandez
Posts: 392
Joined: Wed Jul 31, 2013 1:14 pm
Location: Maldonado - Uruguay
Contact:

Re: soap y dato de retorno

Post by D.Fernandez »

Hi, I need some help in this approach.
Please see this link.
http://forums.fivetechsupport.com/viewt ... 80&start=0
I need it working for Windows 7 32 bits.

Thank you.
Ruben Dario Fernandez
Dario Fernandez
FWH, Harbour, BCC, MySql & MariaDB, tData, Dbf/Cdx
VSCode.
Maldonado - Uruguay
Post Reply