captura de xml retornado por API

381 views
Skip to first unread message

Cleverson

unread,
Dec 28, 2021, 12:07:31 PM12/28/21
to Progress - 4GL
Boa tarde meus Amigos

preciso de um help dos mestres aqui...

estou com um problema ao recuperar um xml retornado no Entity de uma requisição POST de uma API.
quando o XML retornado pela API é pequeno consigo recupera-lo normalmente
porem quando o XML retornado pela API é grande estou recebendo um erro referente ao tipo de conversão invalido .
---------------------------
Cast inválido do OpenEdge.Core.Memptr ao OpenEdge.Core.WidgetHandle. (12869)

faço a conversão dessa forma
hXml = CAST(oResponse:Entity, OpenEdge.Core.WidgetHandle):VALUE NO-ERROR.

de acordo com a mensagem meu CAST, nesse caso de XML grande, deveria ser para MEMPTR ao invés de WidgetHandle, então tratei o erro na conversão acima e fiz o CAST para memptr dessa forma.

ASSIGN oMemptrEntity = CAST( oResponse:Entity, OpenEdge.Core.MEMPTR).
ASSIGN C-ARQ = oMemptrEntity:GetString(1) NO-ERROR.

não recebi mais o erro em questão porem o xml que recebo do getString não vem completo... recebo apenas 2995 caracteres 

fiz o consumo da API pelo Postman e, no Postman, o retorno é um xml completo com mais de 10000 caracteres, 
então o problema acredito que esteja na forma como estou consumindo a API pelo Progress.

Alguém tem experiência em consumo de APIs que retornam XMLs pra me dar um help?

segue abaixo como monto minha requisição.


...
ASSIGN URL-API  = "https://consulta.maisfrete.com.br/api/index.php"
    URL-HOST = "*maisfrete.com.br".

ASSIGN oURI          = URI:Parse(URL-API)
       cClientId     = 'Usuario'
       cClientSecret = 'senha'
       oCredentials  = NEW Credentials(URL-HOST, cClientId, cClientSecret).

ASSIGN oStringMap = NEW StringStringMap().
       oStringMap:PUT('conjunto_de_dados', tipoDados).
       oStringMap:PUT('cnpj',CNPJ).
       oStringMap:PUT('dt_ini',dt-Ini).
       oStringMap:PUT('dt_fim',dt-Fim).
       oStringMap:PUT('id', id).
       oStringMap:PUT('ambiente',STRING(ambiente)).

ASSIGN oLib = ClientLibraryBuilder:Build():sslVerifyHost(YES):LIBRARY NO-ERROR.
ASSIGN oClient = ClientBuilder:Build():KeepCookies(CookieJarBuilder:Build():CookieJar):UsingLibrary(oLib):Client.

ASSIGN oRequest = RequestBuilder
                  :POST( oURI, oStringMap)
                  :UsingBasicAuthentication(oCredentials)
                  :REQUEST.

oResponse = ResponseBuilder:Build():Response.
   
oClient:EXECUTE(oRequest, oResponse) NO-ERROR. 

IF oResponse:StatusCode <> 200 AND
      oResponse:StatusCode <> 401 THEN
       MESSAGE "REQUEST ERROR: " + STRING(oResponse:StatusCode).
 ELSE DO:
      DEFINE VARIABLE hXml       AS HANDLE  NO-UNDO.
      DEFINE VARIABLE hNodeChild AS HANDLE  NO-UNDO.
     
      CREATE X-DOCUMENT hXml.
      CREATE X-NODEREF hNodeChild.

      ERROR-STATUS:ERROR = FALSE.
      //CAST PARA WIDGET
      hXml = CAST(oResponse:Entity, OpenEdge.Core.WidgetHandle):VALUE no-error.

      IF ERROR-STATUS:ERROR AND ERROR-STATUS:NUM-MESSAGES > 0 THEN DO:
         ERROR-STATUS:ERROR = FALSE.
         // CAST PARA MEMPTR
         ASSIGN oMemptrEntity = CAST( oResponse:Entity, OpenEdge.Core.MEMPTR).
         ASSIGN C-ARQ = oMemptrEntity:GetString(1) NO-ERROR.

           COPY-LOB FROM C-ARQ TO FILE ("C:\temp\teste.XML").
      END.
END.








Fabiano Soares da Silva

unread,
Dec 28, 2021, 1:39:09 PM12/28/21
to Progress - 4GL
Boa tarde,
tenta importar para um dataset, com o código abaixo estou importando de um arquivo de uns 20Mb.

define temp-table STDTID
    field STDCODE as character
    field LANGUAGE_CODE as character
    field WORKOBJECT as character
    field WORKTYPE as character
    field DESCR as character
    field VARIANT as character
    field TIMETYPE as character
    field ECC_KATEGORY as character
    field TIME_ as character XML-NODE-NAME "time"
    field TU as character
    field PU as character
    field INVOICE_TEXT as character
    field COMPONENT_CODE as character
    field P3TRUCK as character
    field P3BUS as character
    field P4TRUCK as character
    field P4BUS as character
    field P5TRUCK as character
    field P5BUS as character
    field P6TRUCK as character
    field P4IM as character
    field P5IM as character.

DEFINE DATASET DATA FOR STDTID.

DEFINE VARIABLE lOk AS LOGICAL NO-UNDO.

lOk = DATASET DATA:READ-XML("file",              /* SourceType             */
                                localArquivo, /* File                   */
                                "append",            /* ReadMode               */
                                ?,                   /* SchemaLocation         */
                                ?,                   /* OverrideDefaultMapping */
                                ?,                   /* FieldTypeMapping       */
                                ?).                  /* VerifySchemaMode       */

    for each STDTID:
        assign cont = cont + 1.
    end.

    MESSAGE
        String(cont) " Registros importados do XML"
        VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

Links com vai dados:

--
Recebeu esta mensagem porque subscreveu ao grupo "Progress - 4GL" do Grupos do Google.
Para anular a subscrição deste grupo e parar de receber emails do mesmo, envie um email para progress_4gl...@googlegroups.com.
Para ver este debate na Web, visite https://groups.google.com/d/msgid/progress_4gl/05ae4bd6-2edb-4c2c-ac05-a82cda972bfbn%40googlegroups.com.
Message has been deleted

Cleverson

unread,
Dec 28, 2021, 2:16:01 PM12/28/21
to Progress - 4GL
Boa Tarde Fabiano, 
grato pela rápida resposta

mas nesse caso eu teria que ter o arquivo xml já recuperado da requisição...
e esse é meu problema a principio... 
recupero ele da requisição mas por algum motivo o progress esta me devolvendo só uma parte dele e não completo ...
suspeitei da API a principio, mas consultando via Postman, o xml que recebo é completo, somente via Progress recebo ele 'quebrado'

Fabiano Soares da Silva

unread,
Dec 28, 2021, 2:57:07 PM12/28/21
to Progress - 4GL
Você tem o conteúdo do XML no response, nesse esquema não funciona?

lOk = DATASET DATA:READ-XML("longchar",              /* SourceType             */
                                 oResponse:Entity , /* File                   */

                                "append",            /* ReadMode               */
                                ?,                   /* SchemaLocation         */
                                ?,                   /* OverrideDefaultMapping */
                                ?,                   /* FieldTypeMapping       */
                                ?).                  /* VerifySchemaMode       */

Geraldo Moreira

unread,
Dec 30, 2021, 5:50:30 PM12/30/21
to Progress - 4GL
Eu resolvi uma situação parecida definindo a variável como longchar.

Marcelo Torres

unread,
Jan 3, 2022, 6:57:40 AM1/3/22
to progre...@googlegroups.com
Bom dia Geraldo.

Eu já fiz uma integração com envio e recebimento de XML, usando SOAP.

Na verdade eu abro uma conexão com um URL e faço o envio de uma requisição (em forma de arquivo XML) e recebo um resultado, que também é um XML.

Eu trato tudo como LONGCHAR. Não acho que o seu problema seja no tipo da variável, mas vou colocar a forma como eu faço. Quem sabe você vendo outra forma de fazer pode corrigir alguma coisa no seu código?

O código exemplo está anexado.

Tomara que te ajude em alguma coisa.


Abraço,
Marcelo Torres







exemplo-envio.p
Reply all
Reply to author
Forward
0 new messages