Send xml via POST to API

0

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

String could not be parsed as XML

It keeps 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 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

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

But he lives by giving the error of being string.

    
asked by anonymous 05.12.2018 / 17:07

1 answer

1

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

  • cUrl - the endpoint (single argument required)
  • cGetParms - parameters GET , those that come after ? in URL
  • cPostParms - the payload you want to send
  • nTimeOut - time to give "connection failure" for timeout
  • aHeadStr - vector with headers HTTP to be sent
  • @cHeaderGet - reference to a string where headers will be 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 your code is cXML .

    It also has the function HttpPostXml , but it does not allow headers arbitrary and works with the path of an XML file. I've never felt the need to use it, however, since I avoid XMLs and files when I have everything in memory.

        
    05.12.2018 / 17:20