Amiguinho,
Poderá parecer meio complicado, se voce apenas deseja criar a string citada, os posts anteriores ja o ajudam, mas caso queira integrar em seu sistema funções para o trabalho com XML aqui vai minha dica.
Neste primeiro exemplo apresento um codigo que gera um XML complexo de forma muito simplificada pelo uso de cabeçalhos com comandos formatados:
Código: Selecionar todos
/*
* Teste de integracao XML atraves de arquivos EDX
*/
#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 := "TESTF2B.XML"
EDX oEDX FILE cXMLFile FORMATED
EDX OPEN MARK "soap-env:Envelope" ATTRIB "xmlns:soap-env" VALUE "http://schemas.xmlsoap.org/soap/envelope/" OF oEDX
EDX OPEN MARK "soap-env:Body" OF oEDX
EDX OPEN MARK "m:F2bCobranca" ATTRIB "xmlns:m" VALUE "http://www.f2b.com.br/soap/wsbilling.xsd" OF oEDX
EDX OPEN MARK "mensagem" ;
ATTRIB "data" VALUE "2002-11-06" ;
ATTRIB "numero" VALUE "201636" AUTOCLOSE OF oEDX
EDX OPEN MARK "sacador" ;
ATTRIB "conta" VALUE "9023010001230123" ;
ATTRIB "senha" VALUE "senha123" ;
TAG "José da Silva" AUTOCLOSE OF oEDX
EDX OPEN MARK "cobranca" ;
ATTRIB "valor" VALUE "10.00" ;
ATTRIB "taxa" VALUE "2.50" ;
ATTRIB "tipo_taxa" VALUE "0" ;
ATTRIB "tipo_cobranca" VALUE "" ;
ATTRIB "num_document" VALUE "" OF oEDX
EDX OPEN MARK "demonstrativo" TYPE "" TAG "Cobrança F2b" AUTOCLOSE OF oEDX
EDX OPEN MARK "demonstrativo" TYPE "" TAG "Pague em qualquer banco" AUTOCLOSE OF oEDX
EDX OPEN MARK "desconto" ;
ATTRIB "valor" VALUE "2.00" ;
ATTRIB "tipo_desconto" VALUE "0" ;
ATTRIB "antecedencia" VALUE "5" AUTOCLOSE OF oEDX
EDX OPEN MARK "multa" ;
ATTRIB "valor" VALUE "1.00" ;
ATTRIB "tipo_multa" VALUE "0" ;
ATTRIB "valor_dia" VALUE "0.10" ;
ATTRIB "tipo_multa_dia" VALUE "0" ;
ATTRIB "atraso" VALUE "20" AUTOCLOSE OF oEDX
EDX CLOSE MARK OF oEDX
EDX OPEN MARK "agendamento" ;
ATTRIB "vencimento" VALUE "2002-11-10" ;
ATTRIB "ultimo_dia" VALUE "n" ;
ATTRIB "antecedencia" VALUE "10" ;
ATTRIB "periodicidade" VALUE "1" ;
ATTRIB "periodos" VALUE "12" ;
ATTRIB "sem_vencimento" VALUE "S" ;
TAG "Imediato e Agendado" AUTOCLOSE OF oEDX
EDX OPEN MARK "sacado" ;
ATTRIB "grupo" VALUE "web service" ;
ATTRIB "codigo" VALUE "000001" ;
ATTRIB "envio" VALUE "e" OF oEDX
EDX OPEN MARK "nome" TYPE "" TAG "José Oliveira" AUTOCLOSE OF oEDX
EDX OPEN MARK "email" TYPE "" TAG "joseoliveira@f2b.com.br" AUTOCLOSE OF oEDX
EDX OPEN MARK "email" TYPE "" TAG "joseoliveira@f2b.locaweb.com.br" AUTOCLOSE OF oEDX
EDX OPEN MARK "endereco" ;
ATTRIB "logradouro" VALUE "Rua das Pedras" ;
ATTRIB "numero" VALUE "455" ;
ATTRIB "complemento" VALUE "sala 23" ;
ATTRIB "bairro" VALUE "Itaim Bibi" ;
ATTRIB "cidade" VALUE "São Paulo" ;
ATTRIB "estado" VALUE "SP" ;
ATTRIB "cep" VALUE "04536000" ;
AUTOCLOSE OF oEDX
EDX OPEN MARK "telefone" ;
ATTRIB "ddd" VALUE "11" ;
ATTRIB "numero" VALUE "35551234" ;
AUTOCLOSE OF oEDX
EDX OPEN MARK "telefone_com" ;
ATTRIB "ddd_com" VALUE "22" ;
ATTRIB "numero_com" VALUE "22222222" ;
AUTOCLOSE OF oEDX
EDX OPEN MARK "telefone_cel" ;
ATTRIB "ddd_cel" VALUE "33" ;
ATTRIB "numero_cel" VALUE "33333333" ;
AUTOCLOSE OF oEDX
EDX OPEN MARK "cpf" TYPE "" TAG "12345678909" AUTOCLOSE OF oEDX
EDX CLOSE MARK OF oEDX
EDX OPEN MARK "sacado" OF oEDX
EDX OPEN MARK "nome" TYPE "" TAG "Maria Oliveira" AUTOCLOSE OF oEDX
EDX OPEN MARK "email" TYPE "" TAG "mariaoliveira@f2b.com.br" AUTOCLOSE OF oEDX
EDX CLOSE MARK OF oEDX
EDX OPEN MARK "sacado" OF oEDX
EDX OPEN MARK "nome" TYPE "" TAG "Pedro Oliveira" AUTOCLOSE OF oEDX
EDX OPEN MARK "email" TYPE "" TAG "pedrooliveira@f2b.com.br" AUTOCLOSE OF oEDX
EDX CLOSE MARK OF oEDX
EDX CLOSE MARK OF oEDX
EDX CLOSE MARK OF oEDX
EDX CLOSE MARK OF oEDX
EDX END oEDX
return nil
Veja que usei OPEN MARK para criar TAGs no comando e CLOSE MARK para finaliza-las.
Eis um exemplo do resultado conseguido com um código como o acima:
Código: Selecionar todos
<?xml version="1.0" encoding="ISO-8859-1"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<m:F2bCobranca xmlns:m="http://www.f2b.com.br/soap/wsbilling.xsd">
<mensagem data="2002-11-06" numero="201636"/>
<sacador conta="9080010231230123"
senha="senha123">José da Silva</sacador>
<cobranca valor="10.00"
taxa="2.50"
tipo_taxa="0"
tipo_cobranca=""
num_document="">
<demonstrativo>Cobrança F2b</demonstrativo>
<demonstrativo>Pague em qualquer banco</demonstrativo>
<desconto valor="2.00" tipo_desconto="0" antecedencia="5"/>
<multa valor="1.00" tipo_multa="0" valor_dia="0.10" tipo_multa_dia="0" atraso="20"/>
</cobranca>
<agendamento vencimento="2002-11-10"
ultimo_dia="n"
antecedencia="10"
periodicidade="1"
periodos="12"
sem_vencimento="S">Imediato e Agendado</agendamento>
<sacado grupo="web service" codigo="000001" envio="e">
<nome>José Oliveira</nome>
<email>joseoliveira@f2b.com.br</email>
<email>joseoliveira@f2b.locaweb.com.br</email>
<endereco logradouro="Rua das Pedras" numero="455" complemento="sala 23" bairro="Itaim Bibi" cidade="São Paulo" estado="SP" cep="04536000"/>
<telefone ddd="11" numero="35551234"/>
<telefone_com ddd_com="22" numero_com="22222222"/>
<telefone_cel ddd_cel="33" numero_cel="33333333"/>
<cpf>12345678909</cpf>
</sacado>
<sacado>
<nome>Maria Oliveira</nome>
<email>mariaoliveira@f2b.com.br</email>
</sacado>
<sacado>
<nome>Pedro Oliveira</nome>
<email>pedrooliveira@f2b.com.br</email>
</sacado>
</m:F2bCobranca>
</soap-env:Body>
</soap-env:Envelope>
Para obter sucesso voce deverá usar a classe que proponho TEDXWrite, que aqui modifiquei para usar funções para atender o uso com Clipper:
Código: Selecionar todos
// #include "objects.ch"
// #include "fileio.ch"
#xcommand DEFAULT <uVar1> := <uVal1> ;
[, <uVarN> := <uValN> ] => ;
If( <uVar1> == nil, <uVar1> := <uVal1>, ) ;;
[ If( <uVarN> == nil, <uVarN> := <uValN>, ); ]
FUNCTION TEDXWrite_New( cOut, cVer, cEncode, cSheet, lFormated )
DEFAULT cVer := "1.0"
DEFAULT cEncode := "ISO-8859-1"
lFormated := .t.
cCRLF := If( lFormated, Chr(13)+Chr(10), "" )
aMark := {}
hFile := FCreate( AllTrim( cOut ), 0 )
hLOGFile := FCreate( "EDX.LOG", 0 )
Procesar( '<?xml version="' + cVer + '" encoding="' + cEncode + '"?>' )
IF !Empty( cSheet )
Procesar( '<?xml-stylesheet href="'+ AllTrim( cSheet ) + '" Type="text/xsl"?>' )
END IF
Return( Self )
FUNCTION TEDXWrite_Open( cMark, cType, aAttrib, cTag, lClose, cExt, lRequired )
Local n, cBuffer
DEFAULT cTag := ""
DEFAULT cType := ""
DEFAULT cExt := ""
DEFAULT lRequired := .f.
lRequired := lRequired
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
if lRequired .and. empty( cTag )
cTag := "R.E.Q.U.I.R.E.D"
cLOGBuffer := "The required field "+cMark+" is empty." + cCRLF
FWrite( hLOGFile, cLOGBuffer, Len( cLOGBuffer ) )
endif
cBuffer += '>' + alltrim( cTag ) + If( lClose, '</' + cMark + '>' , "" )
Procesar( cBuffer )
IF lClose
aSize( aMark, Len( aMark ) -1 )
END IF
return ""
FUNCTION TEDXWrite_Close()
Procesar( "</" + aMark[ Len( aMark ) ] + ">" )
aSize( aMark, Len( aMark ) -1 )
return ""
FUNCTION TEDXWrite_End()
Procesar( "" ) // "</xml>" )
FClose( hLOGFile )
FClose( hFile )
return ""
FUNCTION Procesar( cBuffer )
Local nSpaces := If( lFormated, Len( aMark ), 0 )
cBuffer := Space( nSpaces )+ cBuffer + cCRLF
FWrite( hFile, cBuffer, Len( cBuffer ) )
return ""
Aqui esta o conteúdo de EDX.CH para Clipper
Código: Selecionar todos
#xcommand EDX <oEDX> FILE <cOut> ;
[ VERSION <cVer> ] ;
[ ENCODING <cEncode> ] ;
[ STYLESHEET <cSheet> ] ;
[ <lFormated:FORMATED> ];
=> ;
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> ];
[ <lRequired:REQUIRED> ];
<of: OF> <oEDX> ;
=> ;
TEDXWrite_Open( <cMark>, <cType>,;
{ [ { <cAttrib1> ,<uVal1> } ] [, { <(cAttrib2)> ,<(uValN)>} ] },;
<cTag>, <.lAutoClose.>, <uExt>, <.lRequired.>)
#xcommand EDX CLOSE MARK <of: OF> <oEDX> ;
=> ;
TEDXWrite_Close( )
#xcommand EDX SEND <cXMLDoc> ;
URL <cURL> ;
METHOD <cMethod> ;
<of: OF> <oEDX> ;
=> ;
TEDXWrite_Send( <cMethod>, <cURL>, <cXMLDoc> )
#xcommand EDX END <oEDX> ;
=> ;
TEDXWrite_End()
A solução apresentada foi um apanhado do código presente em meu sistema e voce deverá corrigir algum pequeno erro que possa vir a aparecer, sintaxe ou falta de alguma chamada ou variavel.
O exemplo apresentado é usado para integrar meu sistema com WebServices de um serviço online e a classe é usada para gerenciar arquivos para NFe.