Send xml via POST to API

Asked

Viewed 387 times

0

I need to send an xml via post to an api, but it keeps giving the following error:

String could not be parsed as XML

It keeps sending a string instead of actually sending 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 jump the line Then I send the XML as parameter to the Static Function that does the post

eApi(cXML)

Then I read the XML

    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

Code of the POST:

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 keeps giving the error of being string.

  • I believe you are not putting the payload in the right place. As a code of my own, payload is the third parameter (just before timeout)

  • according to the documentation, my payload is in the xml itself, and I did tests on Postman and everything

1 answer

1


You are passing the arguments in switched order. According to the documentation of the function in the TDN, the arguments are as follows, in that order:

  1. cUrl - endpoint (only mandatory argument)
  2. cGetParms - parameters GET, those who come after the ? in the URL
  3. cPostParms - the payload you want to send
  4. nTimeOut - time to give "connection failure" for exceeded time
  5. aHeadStr - vector with the headers HTTP to be sent
  6. @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 is the seventh argument, where in its code is the cXML.

It also has the function HttpPostXml, only that it does not allow to put headers arbitrary 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.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.