Quem não conhece o termo EDI, Eletronic Data Interchange, termo bonito para o que conhecemos como transferencia de arquivos.
No meu caso uso em meu sistema para fazer envio de informações entre filiais de meus clientes.
Para tanto faço uso de arquivos formatados em .XML e só mudo a extensão para diferenciar e não misturar com os tantos arquivos manipulados pelo mesmo.
No exemplo a seguir simulo a geração de um arquivo contendo dados de um cliente e os itens de seu orçamento, que depois de tratados pelo modulo de recebimento atualiza/inclui o cliente no cadastro e inclui um pedido na carteira de vendas.
Vejam que o codigo é bem limpo, e de fácil assimilação e o .XML gerado segue uma estrutura bem definida.
Para gerar a primeira parte usei a classe TXMLWrite( Fred ) e fiz pequeninas mudanças para continuar usando a classe original para outras coisas.
A segunda parte do exemplo apresenta como interpretar um conteudo .XML e obter as informações. Para isto é necessário que o MS XML Toolkit ou MSXML4 esteja instalado.
/*
*
* Teste de integracao XML atraves de arquivos EDX
*
*/
#include "FiveWin.ch"
#include "edx.ch"
#define CR Chr(13)
#define LF Chr(10)
#define BS "\"
Function main()
LOCAL cEDX, cHomeDir
LOCAL cFile, cDOCFile, cXMLFile
PUBLIC oEDX
cXMLFile := "TESTEDX.EDX"
if ! file( cXMLFile )
EDX oEDX FILE cXMLFile FORMATED
EDX OPEN MARK "pedido" ATTRIB "Database" VALUE "25709" OF oEDX
EDX OPEN MARK "cliente" ATTRIB "idcliente" VALUE "803" OF oEDX
EDX OPEN MARK "nome" TYPE "" TAG "JOSE CARLOS DA ROCHA" AUTOCLOSE OF oEDX
EDX OPEN MARK "endereco" TYPE "" TAG "RUA DR MARIO MAURO RAMOS MATTOSO 50" AUTOCLOSE OF oEDX
EDX OPEN MARK "bairro" TYPE "" TAG "PIRITUBA" AUTOCLOSE OF oEDX
EDX OPEN MARK "cidade" TYPE "" TAG "SAO PAULO" AUTOCLOSE OF oEDX
EDX OPEN MARK "estado" TYPE "" TAG "SP" AUTOCLOSE OF oEDX
EDX OPEN MARK "cep" TYPE "" TAG "05171-340" AUTOCLOSE OF oEDX
EDX OPEN MARK "telefone" TYPE "" TAG "(011)3534-3099" AUTOCLOSE OF oEDX
EDX OPEN MARK "cgc" TYPE "" TAG "000.000.000-000" AUTOCLOSE OF oEDX
EDX OPEN MARK "inscr" TYPE "" TAG "00.000.000" AUTOCLOSE OF oEDX
EDX CLOSE MARK OF oEDX // cliente
//
EDX OPEN MARK "item" ATTRIB "Numero" VALUE "1" OF oEDX
EDX OPEN MARK "dataped" TYPE "" TAG "20080926" AUTOCLOSE OF oEDX
EDX OPEN MARK "resumido" TYPE "" TAG "AC1000" AUTOCLOSE OF oEDX
EDX OPEN MARK "descricao" TYPE "" TAG "PRODUTO AC 1000" AUTOCLOSE OF oEDX
EDX OPEN MARK "quantidade" TYPE "" TAG "1.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "valor" TYPE "" TAG "13.600" AUTOCLOSE OF oEDX
EDX OPEN MARK "desconto" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "medidas" OF oEDX
EDX OPEN MARK "largura" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "altura" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "compriment" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX CLOSE MARK OF oEDX // medidas
EDX CLOSE MARK OF oEDX // item
//
EDX OPEN MARK "item" ATTRIB "Numero" VALUE "2" OF oEDX
EDX OPEN MARK "dataped" TYPE "" TAG "20081214" AUTOCLOSE OF oEDX
EDX OPEN MARK "resumido" TYPE "" TAG "AC1020" AUTOCLOSE OF oEDX
EDX OPEN MARK "descricao" TYPE "" TAG "PRODUTO AC 1020" AUTOCLOSE OF oEDX
EDX OPEN MARK "quantidade" TYPE "" TAG "3.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "valor" TYPE "" TAG "5.400" AUTOCLOSE OF oEDX
EDX OPEN MARK "desconto" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "medidas" OF oEDX
EDX OPEN MARK "largura" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "altura" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX OPEN MARK "compriment" TYPE "" TAG "0.000" AUTOCLOSE OF oEDX
EDX CLOSE MARK OF oEDX // medidas
EDX CLOSE MARK OF oEDX // item
EDX CLOSE MARK OF oEDX // pedido
EDX END oEDX
//
endif
cMethod := "POST"
cURL := "http://www.f2b.com.br/WSBilling"
oEDXSend := TOLEAuto():New( "Microsoft.XMLHTTP" )
//oEDXSend:Open( cMethod, cURL, .F. )
//oEDXSend:Send( cXMLFile )
//cEDXBuffer := oEDXSend:ResponseText
cHomeDir := CurDrive() + ":" + BS + CurDir() + BS
cFile := cHomeDir + cXMLFile
oXMLDoc := TOLEAUTO():New("Microsoft.XMLDOM")
oXMLDoc:async := .f.
lSuccess := oXMLDoc:load( cXMLFile )
if lSuccess
x := oXMLDoc:getElementsByTagName( "cliente" )
? oXMLDoc:getElementsByTagName( "nome" ):Item(0):Text , ;
oXMLDoc:getElementsByTagName( "endereco" ):Item(0):Text, ;
oXMLDoc:getElementsByTagName( "bairro" ):Item(0):Text , ;
oXMLDoc:getElementsByTagName( "cidade" ):Item(0):Text , ;
oXMLDoc:getElementsByTagName( "estado" ):Item(0):Text , ;
oXMLDoc:getElementsByTagName( "cep" ):Item(0):Text , ;
oXMLDoc:getElementsByTagName( "telefone" ):Item(0):Text, ;
oXMLDoc:getElementsByTagName( "cgc" ):Item(0):Text , ;
oXMLDoc:getElementsByTagName( "inscr" ):Item(0):Text
x := oXMLDoc:getElementsByTagName( "item" )
for i = 1 to x:length
? oXMLDoc:getElementsByTagName( "dataped" ):Item(i-1):Text , ;
oXMLDoc:getElementsByTagName( "descricao" ):Item(i-1):Text , ;
oXMLDoc:getElementsByTagName( "resumido" ):Item(i-1):Text , ;
oXMLDoc:getElementsByTagName( "quantidade" ):Item(i-1):Text, ;
oXMLDoc:getElementsByTagName( "valor" ):Item(i-1):Text , ;
oXMLDoc:getElementsByTagName( "desconto" ):Item(i-1):Text
next
else
? "erro de abertura"
endif
return nil
#include "edx.prg"
Para completar o exemplo segue os codigos de suporte, EDX.CH:
#xcommand EDX <oEDX> FILE <cOut> ;
[ VERSION <cVer> ] ;
[ ENCODING <cEncode> ] ;
[ STYLESHEET <cSheet> ] ;
[ <lFormated:FORMATED> ];
=> ;
<oEDX> := TEDXWrite():New( <cOut>, <cVer>, <cEncode>, <cSheet>, <.lFormated.> )
#xcommand EDX OPEN MARK <cMark> [ TYPE <cType> ] ;
[ ATTRIB <cAttrib1> VALUE <uVal1> ;
[ ATTRIB <cAttrib2> VALUE <uValN> ]] ;
[ EXTENDED <uExt> ] ;
[ TAG <cTag> ] ;
[ <lAutoClose:AUTOCLOSE> ];
<of: OF> <oEDX> ;
=> ;
<oEDX>:Open( <cMark>, <cType>,;
{ [ { <cAttrib1> ,<uVal1> } ] [, { <(cAttrib2)> ,<(uValN)>} ] },;
<cTag>, <.lAutoClose.>, <uExt>)
#xcommand EDX CLOSE MARK <of: OF> <oEDX> ;
=> ;
<oEDX>:Close( )
#xcommand EDX SEND <cXMLDoc> ;
URL <cURL> ;
METHOD <cMethod> ;
<of: OF> <oEDX> ;
=> ;
<oEDX>:Send( <cMethod>, <cURL>, <cXMLDoc> )
#xcommand EDX END <oEDX> ;
=> ;
<oEDX>:End()
Codigo da classe, EDX.PRG:
*******************************************************************************
* Pruebas para la creacion de fichero xml desde fivewin *
* 01 - 05 - 2002 *
* Enviarme vuestras dudas y sugerencias a fredy@airtel.net *
*******************************************************************************
#include "objects.ch"
#include "fileio.ch"
#xcommand DEFAULT <uVar1> := <uVal1> ;
[, <uVarN> := <uValN> ] => ;
If( <uVar1> == nil, <uVar1> := <uVal1>, ) ;;
[ If( <uVarN> == nil, <uVarN> := <uValN>, ); ]
CLASS TEDXWRITE
DATA hFile, lFormated, cCRLF, aMark
METHOD New( cOut, cVer, cEncode, cSheet, lFormated ) CONSTRUCTOR
METHOD Open( cMark, cType, aAttrib, cTag, lClose, cExt )
METHOD End()
METHOD Procesar( cText )
METHOD Send( cMethod, cURL, cXMLDoc )
METHOD Close()
ENDCLASS
METHOD New( cOut, cVer, cEncode, cSheet, lFormated ) CLASS TEDXWRITE
DEFAULT cVer := "1.0"
DEFAULT cEncode := "ISO-8859-1"
//DEFAULT
::lFormated := .t.
::cCRLF := If( lFormated, Chr(13)+Chr(10), "" )
::aMark := {}
::hFile := FCreate( AllTrim( cOut ), 0 )
::Procesar( '<?xml version="' + cVer + '" encoding="' + cEncode + '"?>' )
IF !Empty( cSheet )
::Procesar( '<?xml-stylesheet href="'+ AllTrim( cSheet ) + '" Type="text/xsl"?>' )
END IF
Return( Self )
METHOD Open( cMark, cType, aAttrib, cTag, lClose, cExt ) CLASS TEDXWRITE
Local n, cBuffer
DEFAULT cTag := ""
DEFAULT cType := ""
DEFAULT cExt := ""
aAdd( ::aMark, cMark )
cBuffer := '<' + cMark
//IF Len( ::aMark ) == 1
// cBuffer += ' xmlns:dt="urn:schemas-microsoft-com:datatypes"'
// xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
// xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
//END IF
IF !Empty( cType )
cBuffer += ' dt:dt= "' + cType + '"'
END IF
IF Len( aAttrib ) > 0
FOR n := 1 TO Len( aAttrib )
cBuffer += ' '+ aAttrib[n,1] + ' = "' + aAttrib[n,2] + '" '
NEXT
END IF
cBuffer += '>' + alltrim( cTag ) + If( lClose, '</' + cMark + '>' , "" )
::Procesar( cBuffer )
IF lClose
aSize( ::aMark, Len( ::aMark ) -1 )
END IF
METHOD Close() CLASS TEDXWRITE
::Procesar( "</" + ::aMark[ Len( ::aMark ) ] + ">" )
aSize( ::aMark, Len( ::aMark ) -1 )
METHOD End() CLASS TEDXWRITE
::Procesar( "" ) // "</xml>" )
FClose( ::hFile )
METHOD Send( cMethod, cURL, cXMLDoc ) CLASS TEDXWRITE
oEDXSend := TOLEAuto():New( "Microsoft.XMLHTTP" )
oEDXSend:Open( cMethod, cURL, .F. )
oEDXSend:Send( cXMLDoc )
//cEDXBuffer := oEDXSend:ResponseText
return "" // cEDXBuffer
METHOD Procesar( cBuffer ) CLASS TEDXWRITE
Local nSpaces := If( ::lFormated, Len( ::aMark ), 0 )
cBuffer := Space( nSpaces )+ cBuffer + ::cCRLF
FWrite( ::hFile, cBuffer, Len( cBuffer ) )
return