Send xml via post to API
I need to send an xml via post to an api, but it gets the following error:
String could not be parsed as XML
It gets sending a string, instead of actually sending the XML.
The code to create XML:
//Monta o XML
cXML += "<?xml version='1.0' encoding='UTF-8' ?>" + SL
cXML += "<maxfrota>"+ SL
cXML += "<usuario>"+Alltrim('123')+"</usuario>" + SL
cXML += "<chave>"+Alltrim('123')+"</chave>" + SL
cXML += "<opcoes>" + SL
cXML += "<reordenar_entregas>"+Alltrim('0')+"</reordenar_entregas>" + SL //NAO PRECISA
cXML += "</opcoes>" + SL
cXML += "<acao>"+Alltrim('adicionar')+"</acao>" + SL
While !QRY_SB1->(EoF())
cXML += " <dados>"+ SL
cXML += " <entregas>"+ SL
cXML += " <entrega>"+ SL
cXML += " <origem>"+ SL
cXML += " <codigo>"+Alltrim('')+"</codigo>" + SL
cXML += " <codigo_externo>"+Alltrim('1')+"</codigo_externo>" + SL
cXML += " </origem>"+ SL
cXML += " <lote>"+Alltrim(cCarga)+"</lote>" + SL
cXML += " <lote_principal>"+Alltrim('')+"</lote_principal>" + SL //NAO VAMOS COLOCAR
cXML += " <numero>"+Alltrim(MOTORI->PEDIDO)+"</numero>" + SL
cXML += " <data_pedido>"+Alltrim('2014-10-24 08:00:00')+"</data_pedido>" + SL
cXML += " <nota_fiscal>"+Alltrim(QRY_SB1->F2_DOC)+"</nota_fiscal>" + SL //NOTA FISCAL {OK}
cXML += " <data_emissao>"+Alltrim(QRY_SB1->F2_EMISSAO)+"</data_emissao>" + SL
cXML += " <chave_nota_fiscal>"+Alltrim('76278164782364781269879')+"</chave_nota_fiscal>" + SL
cXML += " <valor>"+Alltrim('5549.99')+"</valor>" + SL
cXML += " <cliente>"+ SL
cXML += " <codigo>"+Alltrim(QRY_SB1->F2_CLIENT)+"</codigo>" + SL
cXML += " <nome>"+Alltrim(QRY_SB1->A1_NOME)+"</nome>" + SL
cXML += " <endereco>"+Alltrim(QRY_SB1->A1_ENDENT)+"</endereco>" + SL
cXML += " <endereco_detalhado>"+ SL
cXML += " <logradouro>"+Alltrim(QRY_SB1->A1_ENDENT)+"</logradouro>" + SL
cXML += " <numero>"+Alltrim(QRY_SB1->A1_YNUMT)+"</numero>" + SL
cXML += " <bairro>"+Alltrim(QRY_SB1->A1_BAIRROE)+"</bairro>" + SL
cXML += " <cidade>"+Alltrim(QRY_SB1->A1_MUN)+"</cidade>" + SL
cXML += " <uf>"+Alltrim(QRY_SB1->A1_EST)+"</uf>" + SL
cXML += " <cep>"+Alltrim(QRY_SB1->A1_CEP)+"</cep>" + SL
cXML += " <informacao_adicional>"+Alltrim(QRY_SB1->A1_REFEREN)+"</informacao_adicional>" + SL
cXML += " </endereco_detalhado>"+ SL
cXML += " <telefone>"+Alltrim(QRY_SB1->A1_TEL)+"</telefone>" + SL
cXML += " <email>"+Alltrim(QRY_SB1->A1_EMAIL)+"</email>" + SL
cXML += " <cidade>"+Alltrim(QRY_SB1->A1_MUN)+"</cidade>" + SL
cXML += " <latitude>"+Alltrim('-5.9115545')+"</latitude>" + SL //NO MOMENTO NAO BOTAREMOS
cXML += " <longitude>"+Alltrim('-35.2713164')+"</longitude>" + SL //NO MOMENTO NAO BOTAREMOS
cXML += " <consultor>"+Alltrim('1')+"</consultor>" + SL //ID DO CONSULTOR DO SEU SISTEMA
cXML += " </cliente>"+ SL
cXML += " <janela>"+ SL
cXML += " <data_hora_inicial>"+Alltrim('')+"</data_hora_inicial>" + SL //NAO COLOCAREMOS NO MOMENTO
cXML += " <data_hora_final>"+Alltrim('')+"</data_hora_final>" + SL //NAO COLOCAREMOS NO MOMENTO
cXML += " </janela>"+ SL
cXML += " <tempo_estimado>"+Alltrim('40')+"</tempo_estimado>" + SL //NAO COLOCAREMOS NO MOMENTO
cXML += " <data_limite>"+Alltrim('')+"</data_limite>" + SL //PROCURAR SABER
cXML += " <hora_limite>"+Alltrim('23:59:59')+"</hora_limite>" + SL //PROCURAR SABER
cXML += " <tolerancia>"+Alltrim('0')+"</tolerancia>" + SL
cXML += " <posicao>"+Alltrim('1')+"</posicao>" + SL //NAO COLOCAREMOS NO MOMENTO
cXML += " <distancia_prevista>"+Alltrim('1')+"</distancia_prevista>" + SL //NAO COLOCAREMOS NO MOMENTO
cXML += " <veiculo>"+ SL
cXML += " <codigo>"+Alltrim('')+"</codigo>" + SL
cXML += " <codigo_externo>"+Alltrim('PFX-5099')+"</codigo_externo>" + SL
cXML += " </veiculo>"+ SL
cXML += " <motorista>"+ SL
cXML += " <nome>"+Alltrim(MOTORI->DA4_NOME)+"</nome>" + SL
cXML += " <cpf>"+Alltrim('')+"</cpf>" + SL //NAO TEMOS O CPF, SÓ O CÓDIGO
cXML += " </motorista>"+ SL
cXML += " <rota>"+ SL
cXML += " <codigo>"+Alltrim('')+"</codigo>" + SL //DEVERÁ VIM VAZIO
cXML += " <codigo_externo>"+Alltrim('1')+"</codigo_externo>" + SL //PROCURAR SE TIVERMOS
cXML += " </rota>"+ SL
cXML += " <peso>"+Alltrim('0')+"</peso>" + SL //NAO TEMOS
cXML += " <volume>"+Alltrim('0')+"</volume>" + SL //NAO TEMOS
cXML += " <ocupacao>"+Alltrim('12.5')+"</ocupacao>" + SL //PROCURAR SABER
cXML += " <itens>"+ SL
cXML += " <item>"+ SL
cXML += " <codigo_externo>"+Alltrim('00021759250001')+"</codigo_externo>" + SL //PROCURAR SABER SE TEMOS (Código de barras do Volume a ser conferido)
cXML += " </item>"+ SL
cXML += " </itens>"+ SL
cXML += "</entrega>" + SL
cXML += "</entregas>" + SL
cXML += " <rotas>"+ SL
cXML += " <rota>"+ SL
cXML += " <codigo_externo>"+Alltrim('')+"</codigo_externo>" + SL //PROCURAR SABER SE TEMOS
cXML += " <lote>"+Alltrim(cCarga)+"</lote>" + SL
cXML += " <polilinha>"+Alltrim('_p~iF~ps|U_ulLnnqC_mqNvxq`@')+"</polilinha>" + SL //NAO TEMOS
cXML += " <ocupacao_total>"+Alltrim('83.75')+"</ocupacao_total>" + SL //PROCURAR SABER SE TEMOS
cXML += " <distancia_prevista_total>"+Alltrim('30816')+"</distancia_prevista_total>" + SL //NAO TEMOS
cXML += " </rota>"+ SL
cXML += " </rotas>"+ SL
cXML += "</dados>" + SL
nAtu++
QRY_SB1->(DbSkip())
EndDo
QRY_SB1->(DbCloseArea())
cXML += "</maxfrota>" + SL
the + SL
is to skip line
Then I send the XML as a parameter to the static function that makes the post
eApi(cXML)
Then I do the XML reading
Static Function fLeXML(aCarga)
Local oLido := Nil
Local cReplace := "_"
Local cErros := ""
Local cAvisos := ""
Local cMsg := ""
Local cCar := aCarga
//Se o arquivo existir
If File(cDirect+cArquivo+cCar+cValtoChar(nElem)+".xml")
//Lendo o arquivo com XMLParser (lê a string), caso queira ler o arquivo direto, utilize o XMLParserFile (o arquivo deve estar dentro da system)
oLido := XmlParser(MemoRead(cDirect+cArquivo+cCar+cValtoChar(nElem)+".xml"), cReplace, @cErros, @cAvisos)
//Se tiver erros, mostra ao usuário
If !Empty(cErros)
Aviso('Atenção', "Erros: "+cErros, {'Ok'}, 03)
EndIf
//Se tiver avisos, mostra ao usuário
If !Empty(cAvisos)
Aviso('Atenção', "Avisos: "+cAvisos, {'Ok'}, 03)
EndIf
//Mensagem de sucesso
MSGALERT( "XML criado com sucesso!" )
//Mostrando a mensagem do xml lido
Aviso('Atenção', cMsg, {'Ok'}, 03)
EndIf
Return
Post Code:
Static Function eApi(cXML)
nTimeOut := 120
aHeadOut := {}
cHeadRet := ""
sPostRet := ""
aAdd(aHeadOut,'User-Agent: Mozilla/4.0 (compatible; Protheus '+GetBuild()+')')
aadd(aHeadOut,'Content-Type: application/xml')
cUrl1 := ("API AQUI")
sPostRet := HttpPost(cUrl1,,,nTimeOut,aHeadOut,@cHeadRet, cXML)
ALERT(sPostRet)
return
Only he lives giving the error of ser string.
1 answers
You are passing the arguments in Changed order. According to the documentation of the function in the TDN , the arguments are as follows, in this order:
-
cUrl
- the endpoint (only required argument) -
cGetParms
- parametersGET
, those that comes after the?
in the URL -
cPostParms
- the payload you want to send -
nTimeOut
- time to give "connection failure" for time exceeded -
aHeadStr
- vector with the HTTP headers to be sent -
@cHeaderGet
- reference to a string where the headers received from the server
Your third argument is empty, so ADVPL puts nil
during the call (see more ).
The correction would be to change the order of the arguments:
sPostRet := HttpPost(cUrl1,,cXML,nTimeOut,aHeadOut,@cHeadRet)
There is no documentation that explains what the seventh argument is, where in your code is cXML
.
Also has the function HttpPostXml
, only he does not allows you to place arbitrary headers and works with the path of an XML file. I never felt the need to use it, however, since I avoid XMLs and files when I have everything in memory.