Página 1 de 1

Um pouco sobre Web-Services

Enviado: 09 Dez 2006 04:30
por rochinha
Amiguinhos

Bom, o XML é um padrão de arquivo multihierarquico o qual sua estrutura não tem um fim definido, pois podemos ter muitos nós aninhados dentro dos outros, mas para não confundir sempre usamos no maximo 2 ou 3.

No XML a seguir capturado via web-service em 5Win/Harbour voce podem ver uma pequena estrutura:

Código: Selecionar todos

<?xml version="1.0" encoding="ISO-8859-1" ?>
   <calculo_precos>
      <versao_arquivo>1.0</versao_arquivo>
      <dados_postais>
         <servico>40010</servico>
         <servico_nome>SEDEX</servico_nome>
         <uf_origem></uf_origem>
         <local_origem></local_origem>
         <cep_origem>05171340</cep_origem>
         <uf_destino></uf_destino>
         <local_destino></local_destino>
         <cep_destino>88330000</cep_destino>
         <peso>31</peso>
         <mao_propria>0</mao_propria>
         <aviso_recebimento>0</aviso_recebimento>
         <valor_declarado>0</valor_declarado>
         <tarifa_valor_declarado>0</tarifa_valor_declarado>
         <preco_postal>0</preco_postal>
      </dados_postais>
      <erro>
         <codigo>-4</codigo>
         <descricao>Peso excedido</descricao>
      </erro>
   </calculo_precos>
</xml>
Portanto o trabalho com nós do mesmo não é assim tão fácil de se manipular

Com o exemplo acima minha função XMLGet() cai como uma luva para obter dados do arquivo.

No codigo que segue apresento o .RC da DIALOGo principal de interface com o usuário:

Salve como SEDEX.RC

Código: Selecionar todos

Sedex DIALOG 28, 62, 267, 175
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "DIALOG_1"
FONT 8, "MS Sans Serif"
{
 EDITTEXT 101, 37, 17, 47, 12
 EDITTEXT 102, 168, 17, 47, 12
 EDITTEXT 103, 78, 50, 67, 12
 PUSHBUTTON "Calcular Envio", 105, 149, 50, 107, 27
 EDITTEXT 104, 78, 65, 67, 12
 LTEXT "Nenhuma operação em curso.", 106, 10, 97, 247, 67
 GROUPBOX "Origem", -1, 4, 5, 128, 32, BS_GROUPBOX
 GROUPBOX "Calculo", -1, 4, 38, 259, 46, BS_GROUPBOX
 GROUPBOX "Mensagem", -1, 4, 87, 259, 82, BS_GROUPBOX
 LTEXT "CEP:", -1, 9, 18, 26, 8
 LTEXT "Peso em Gramas:", -1, 10, 52, 60, 8
 LTEXT "Total a Pagar R$:", -1, 11, 66, 60, 8
 GROUPBOX "Destino", -1, 135, 5, 128, 32, BS_GROUPBOX
 LTEXT "CEP:", -1, 140, 18, 26, 8
}
O codigo a seguir é um web-service que tem por função passar parâmetros ao servidor de serviços dos Correios afim de trazer uma resposta dada por seus serviços on-line.

Imagine que o mesmo método poderá ser usado para enviar dados ao Seraza e SPC e trazer o resultado da pesquisa validando ou não o crédito de um cliente.

O código a seguir, feito em 5Win 2.7 e Harbour 45 pode ser adaptado a qualquer versão ou até a qualquer GUI que não 5Win e demonstra de forma clara com é feito este trabalho.

Salve como SEDEX.PRG

Código: Selecionar todos

#include "fivewin.ch"

static xDLL,oGet,oSay
Function Main()
   local oDlg, oFont
   local cCEP1:=space(9), cCEP2:=space(9), cPESO:=0 , cTOTAL := 0
   DEFINE FONT oFont NAME "ARIAL" SIZE 00,-12 BOLD
   SET _3DLOOK ON
   DEFINE DIALOG oDlg RESOURCE "Sedex" TITLE "Correios - Sedex"
          REDEFINE GET oGet101 VAR cCEP1  PICTURE "99999-999" ID 101 OF oDlg
          REDEFINE GET oGet102 VAR cCEP2  PICTURE "99999-999" ID 102 OF oDlg

          REDEFINE GET oGet103 VAR cPESO  PICTURE "999999999"    ID 103 OF oDlg
          REDEFINE GET oGet104 VAR cTOTAL PICTURE "@E 99,999.99" ID 104 OF oDlg
          REDEFINE BUTTON ID 105 OF oDlg ACTION Consulta(cCEP1,cCEP2,cPESO,oGet104,oSay106)

          REDEFINE SAY oSay106 MEMO ID 106 OF oDlg COLOR nRGB(255,0,0),getsyscolor(15)
   ACTIVATE DIALOG oDlg CENTERED
   return nil

Function Consulta(cCepOrigem,cCepDestino,cPeso,oTotal,oSay)
   local oRs, ws
   ws := TdWebService():new()
   oSay:SetText( "Aguarde. consulta base de dados" )
   cXMLSedex := ws:OpenWS( "http://www.correios.com.br/encomendas/precos/calculo.cfm?" +;
                      "&cepOrigem="+cCepOrigem+;
                      "&cepDestino="+cCepDestino+;
                      "&peso="+alltrim(str(cPeso))+;
                      "&resposta=xml" ) 
   ws:end()

   oSay:SetText( "Aguarde. salvando o resultado" )
   MemoWrit( "sedex.xml", cXMLSedex )

   cXMLPreco := XMLGet( "preco_postal", cXMLSedex )
   cXMLErros := XMLGet( "descricao"   , cXMLSedex )

   cTotal := transf( val( cXMLPreco ), "@E 99,999.99" )
   oGet104:Refresh()

   oGet104:SetText( cTotal )
   oSay:SetText( iif( empty( cXMLErros ), "Operacao bem sucedida", cXMLErros ) )
   return nil

Function XMLGet( XMLField, XMLFile )
   XMLField    := alltrim( XMLField )
   XMLFieldINI := rat( "<"+XMLField+">", XMLFile ) + len( "<"+XMLField+">" ) 
   XMLFieldEND := rat( "</"+XMLField+">", XMLFile ) - XMLFieldINI
   return substr( XMLFile, XMLFieldINI, XMLFieldEND )

#include "Websrvce.prg"
Abaixo vemos a classe WebService que é a responsável por fazer a ponte entre nosso aplicativo e o ponto distante do mesmo.

Salve como WEBSRVCE.PRG

Código: Selecionar todos

/*
 *
 * Classe WebService
 *
 */
#include "dll.ch"

//static xdll
CLASS TdWebService
     DATA hOpen
     DATA sbuffer HIDDEN
     DATA xDLL HIDDEN

     METHOD New(buffersize) CONSTRUCTOR

     METHOD OpenWS(url)

     METHOD End()
ENDCLASS
*****************************
METHOD New(conexion,buffersize) CLASS TdWebService
DEFAULT buffersize:=3200
   ::sbuffer:=buffersize
   xDll:=LoadLib32("wininet.dll")
   ::hOpen = InternetOpen("TdWebService", 1,,, 0)
RETURN Self
*****************************
METHOD OpenWS(url) CLASS TdWebService
local hFile,ret,xml
   hFile = InternetOpenUrl(::hOpen, url,"",0,,0)
   xml:=space(::sbuffer)
   InternetReadFile(hFile, @xml, ::sbuffer, @Ret)
return subst(alltrim(xml),1,len(alltrim(xml))-5)
*****************************
METHOD End() CLASS TdWebService
   FreeLib32(xDll)
return nil
*****************************

DLL32 FUNCTION InternetOpen( cApp as LPSTR, n1 AS DWORD, n2 AS LPSTR, n3 AS LPSTR,;
                             n4 AS DWORD ) AS LONG PASCAL ;
                             FROM "InternetOpenA" LIB xdll
Dll32 Function InternetReadFile(hFile As 7, @sBuffer As 8, lNumBytesToRead As 7, @lNumberOfBytesRead As 7) As 7 PASCAL Lib xdll
Dll32 Function InternetOpenUrl(hInternetSession As 7, lpszUrl As 8, lpszHeaders As 8, dwHeadersLength As 7, dwFlags As 7, dwContext As 7) As 7 FROM "InternetOpenUrlA" PASCAL Lib xdll
DLL32 FUNCTION InternetCloseHandle( hSession AS LONG ) AS BOOL PASCAL LIB xdll
Tenho feito outros web-services para meu aplicativo e sei que mesmo ainda usando o xBase vejo que não existem mais segredos e nem barreiras que eu não consiga transpor, além do próprio Céu.

"E que Deus seja louvado!"

Enviado: 28 Abr 2007 17:03
por evandro
Olá,
Imagine que o mesmo método poderá ser usado para enviar dados ao Seraza e SPC e trazer o resultado da pesquisa validando ou não o crédito de um cliente.
Preciso fazer estas consultas, SPC e Serasa, além de consultar um CEP. Você tem maiores detalhes? Não consegui localizar Consulta via web-service nem para o SPC nem para o Serasa. Nos Correios, a consulta de CEP não funcionou.

Enviado: 30 Abr 2007 15:11
por rochinha
Amiguinho

O SERASA oferece sim estes servicos em varios formatos, inclusive XML e voce pode incorpora-los aos seus sistemas de forma facilitada.

O unico impecilho é que voce deverá ser uma empresa associada e que faz uso de algum serviço do SERASA.

Outra empresa que oferece serviços identicos é a SCI EquiFAX, www.SCI.com.br

Boa sorte.

Enviado: 30 Abr 2007 16:15
por evandro
Olá,
O unico impecilho é que voce deverá ser uma empresa associada e que faz uso de algum serviço do SERASA.
Isto não é problema. Meu cliente já tem convênio com o Serasa. Só não consegui, nem do representante do Serasa (comercial, diga-se de passagem) alguma informação neste sentido. E o leiaute que tenho comigo, alpem de ser muito complexo, não é via WebService/XML. Por isso solicitei maiores informações. Se tiver.....

Criar XML

Enviado: 24 Mai 2007 14:35
por kachenco
Colega, eu preciso criar um XML usando o xhb.com puro, como posso fazer isso ??

Estou tentando com as funcoes TXmlDocument e TXmlNode, mas sem sucesso !!! :(

Será que pode me ajudar ??

Enviado: 24 Mai 2007 16:54
por rochinha
Amiguinho

Voce tem em mao a documentacao que te enviaram, ou pequenos programas autenticadores?

envie me para analisar

em irochinha@itelefonica.com.br

XML

Enviado: 25 Mai 2007 09:03
por kachenco
Foi em PVT.

Agradeço qqr ajuda !!

Um pouco sobre Web-Services

Enviado: 30 Abr 2015 14:04
por rochinha
Amiguinhos,

Para melhorar o uso da função XMLGet() coloco mais um teste:

Código: Selecionar todos

   ...
   cXMLTotal := MemoRead( "meu.xml" )

   if empty(XMLGet( "logradouro", cRs ))
      MsgStop( "LOGRADOURO nao encontrado." ) 
      return .t.
   endif
   
   cXMLTexto := XMLGet( "logradouro", cRs )

   ? cXMLTexto
   
   return nil
Função XMLGet():

Código: Selecionar todos

Function XMLGet( XMLField, XMLFile )
   XMLField    := alltrim( XMLField )
   XMLFieldINI := rat( "<"+XMLField+">", XMLFile ) + len( "<"+XMLField+">" ) 
   XMLFieldEND := rat( "</"+XMLField+">", XMLFile ) - XMLFieldINI
   return alltrim(substr( XMLFile, XMLFieldINI, XMLFieldEND ))
Ao usar .XML nas respostas a pesquisas em webservices, não tem jeito, temos de buscar padrões. Se este padrões não estão no conteúdo do .XML não devemos esperar que nossa aplicação aborte com erros, por isso, devemos prevê-los.

No meu exemplo eu previ a existência da variável logradouro, se ela não for encontrada é porque o conteúdo do .XML não a contém.

Se tiver de testar cada campo do qual necessito recuperar seu conteúdo, melhor, pois posso estipular respostas ao usuário de forma que ele saiba o que está faltando e corrigir.

Isto é uma pré-validação sem schemas.