Página 1 de 1

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 30 Jul 2016 20:16
por asimoes
Pessoal,

Desenvolvi semana passada uma rotina que consome um ws que retorna um objeto json, pensei comigo, ferrou como vou resolver isso, mas o danado do harbour tem função pra isso e resolveu.

hb_jsondecode devolve uma hash table e o interessante é que mostra todas a propriedades do objeto exemplo abaixo.

Código: Selecionar todos

      cRetorno:=oWSPGM:oServerWS:responseBody
      
      aResposta:={}
      
      nLen := hb_jsondecode( cRetorno, @aResposta )
      
      If ValType(aResposta) = "H"
         If Len(aResposta) != 0
            aRetorno:={aResposta["numCda"],;
                       aResposta["codErro"],;
                       aResposta["datProcesso"]}
         Else
            Break
         Endif
      Else
         Break
      Endif

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 30 Jul 2016 20:36
por rochinha
Amiguinhos,

asimoes
Qual versão do Harbour e qual biblioteca voce agregou para tal?

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 30 Jul 2016 21:45
por asimoes
Olá Rochinha,

Harbour 3.4 fork

Até onde eu sei a função hb_JSONDecode é parte integrante do harbour (rtl) não precisa linkar nenhuma lib da contrib

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 30 Jul 2016 21:50
por asimoes
Outra forma de uso:

Código: Selecionar todos

    Try
     oHttp:= TIpClientHttp():new( oWSPGM:cUrlWS )
      
      If ! oHttp:open()
         Break
      Endif
      
      cJSON := oHttp:readAll()
      oHttp:close()
      
      hb_JSONDecode( cJSON, @hJSON )

      * Aqui testa a key da hash table
      If !hb_HHAsKey(hJSON, "numCda") .AND. ;
         !hb_HHAsKey(hJSON, "codErro") .AND. ;
         !hb_HHAsKey(hJSON, "dataInscricao")
         Break
      Endif
      aRetorno:={hJSON["numCda"],;
                 hJSON["codErro"],;
                 hJSON["dataInscricao"]}
   Catch
      aRetorno:={}
   End

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 17 Abr 2023 15:12
por malcarli
Boa tarde, entrando no mundo Json. Peguei exemplos, está até funcionando a contento. Só não consegui pegar atividade_principal, qsa e atividades _segundárias.

Alguém poderia ajudar como conseguir isto? Obg

Para pegar dados simples usei assim:

Código: Selecionar todos

      hb_JSONDecode(Hb_OemToAnsi(oHttp:responseText), @hCnpj)

      _SetValue([Txt_1] , [fConsultaCnpj], hCnpj["cnpj"])

Código: Selecionar todos

{
  "abertura": "30/08/2010",
  "situacao": "ATIVA",
  "tipo": "MATRIZ",
  "nome": "EMPRESA - GESTAO EM SAUDE OCUPACIONAL LTDA",
  "fantasia": "EMPRESA",
  "porte": "DEMAIS",
  "natureza_juridica": "206-2 - Sociedade Empresária Limitada",
  "atividade_principal": [
    {
      "code": "86.30-5-02",
      "text": "Atividade médica ambulatorial com recursos para realização de exames complementares"
    }
  ],
  "qsa": [
    {
      "nome": "FULANO DE TAL",
      "qual": "49-Sócio-Administrador"
    },
    {
      "nome": "SICRANO DE TAL",
      "qual": "49-Sócio-Administrador"
    }
  ],
  "logradouro": "AVENIDA SEM NOME",
  "numero": "123",
  "municipio": "MARILIA",
  "bairro": "PALMITAL",
  "uf": "SP",
  "cep": "17.509-001",
  "email": "empresa@email.med.br",
  "telefone": "(14) 3999-9999",
  "data_situacao": "30/08/2010",
  "cnpj": "12.245.678/0001-10",
  "ultima_atualizacao": "2023-03-11T23:59:59.000Z",
  "status": "OK",
  "complemento": "",
  "efr": "",
  "motivo_situacao": "",
  "situacao_especial": "",
  "data_situacao_especial": "",
  "atividades_secundarias": [
    {
      "code": "00.00-0-00",
      "text": "Não informada"
    }
  ],
  "capital_social": "4000.00",
  "extra": {},
  "billing": {
    "free": true,
    "database": true
  }
}

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 17 Abr 2023 15:31
por JoséQuintas
Nem só de hash array vive o json.
Tem array no meio.

Desenvolvi uma rotina legalzinha pra facilitar enxergar isso, vou ver se encontro aqui.

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 17 Abr 2023 15:50
por JoséQuintas

Código: Selecionar todos


PROCEDURE Main

   LOCAL txt, json

   SetMode(300,120)
   CLS
   txt := '{ "abertura": "30/08/2010", "situacao": "ATIVA", "tipo": "MATRIZ", "nome": "EMPRESA - GESTAO EM SAUDE OCUPACIONAL LTDA", "fantasia": "EMPRESA", "porte": "DEMAIS", "natureza_juridica": "206-2 - Sociedade Empresária Limitada", "atividade_principal": [ { "code": "86.30-5-02", "text": "Atividade médica ambulatorial com recursos para realização de exames complementares" } ], "qsa": [ { "nome": "FULANO DE TAL", "qual": "49-Sócio-Administrador" }, { "nome": "SICRANO DE TAL", "qual": "49-Sócio-Administrador" } ], "logradouro": "AVENIDA SEM NOME", "numero": "123", "municipio": "MARILIA", "bairro": "PALMITAL", "uf": "SP", "cep": "17.509-001", "email": "empresa@email.med.br", "telefone": "(14) 3999-9999", "data_situacao": "30/08/2010", "cnpj": "12.245.678/0001-10", "ultima_atualizacao": "2023-03-11T23:59:59.000Z", "status": "OK", "complemento": "", "efr": "", "motivo_situacao": "", "situacao_especial": "", "data_situacao_especial": "", "atividades_secundarias": [ { "code": "00.00-0-00", "text": "Não informada" } ], "capital_social": "4000.00", "extra": {}, "billing": { "free": true, "database": true } }'
   json := hb_jsonDecode( txt )
   ShowJson( json, "" )
   Inkey(0)

   RETURN


FUNCTION ShowJson( aHash, cTxt )

   LOCAL oElement

   IF ValType( aHash ) $ "NCDL" .OR. aHash == NIL
      ? cTxt, aHash
      Inkey(1)
   ELSEIF ValType( aHash ) == "A"
      FOR EACH oElement IN aHash
         ShowJson( oElement, cTxt + "[ " + Ltrim( Str( oElement:__EnumIndex ) ) + " ]" )
      NEXT
   ELSEIF ValType( aHash ) == "H"
      FOR EACH oElement IN aHash
            ShowJson( oElement, cTxt + '[ "' + hb_hKeyAt( aHash, oElement:__EnumIndex ) + '" ]' )
      NEXT
   ELSE
      ? cTxt, "***** nao identificado ***"
      Inkey(1)
   ENDIF

   RETURN NIL
json.png

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 17 Abr 2023 15:53
por JoséQuintas
json.png
Mas olhando pelo json, dá pra identificar aonde entra array, é o colchete "[ ]"

na imagem, atividades_secundarias é um array.

Código: Selecionar todos

aList := x[ "atividades_secundarias" ]
FOR EACH Item IN aList
   ? item[ "code" ]
   ? item[ "text" ]
NEXT
? x[ "atividades_secundarias" ][ 1 ][ "code" ]
? x[ "atividades_secundarias" ][ 1 ][ "text" ]
array porque é uma lista sem tamanho pré-definido.

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 17 Abr 2023 16:13
por JoséQuintas

Código: Selecionar todos


FUNCTION ShowJson( aHash, cTxt )

   LOCAL oElement

   IF ValType( aHash ) $ "NCDL" .OR. aHash == NIL
      ? cTxt, aHash
   ELSEIF ValType( aHash ) == "A"
      FOR EACH oElement IN aHash
         ShowJson( oElement, cTxt + "[ " + Ltrim( Str( oElement:__EnumIndex ) ) + " ]" )
      NEXT
   ELSEIF ValType( aHash ) == "H"
      FOR EACH oElement IN aHash
            ShowJson( oElement, cTxt + '[ "' + hb_hKeyAt( aHash, oElement:__EnumIndex ) + '" ]' )
      NEXT
   ELSE
      ? cTxt, "***** nao identificado ***"
   ENDIF

   RETURN NIL
Voltando à função.
Até que ela não tem nada demais, mas é recursiva.
Ela pega CADA ELEMENTO da variável pra mostrar na tela.
Se o elemento for uma lista, array ou hash, vai chamando ela mesma pra mostrar os sub-elementos
Conforme faz isso, vai adicionando o nível no texto, pra ficar visível pra humanos.

Código: Selecionar todos

   ELSEIF ValType( aHash ) == "A"
      FOR EACH oElement IN aHash
         ShowJson( oElement, cTxt + "[ " + Ltrim( Str( oElement:__EnumIndex ) ) + " ]" )
      NEXT
Acima array, que é numerado de um em um, __EnumIndex é o número sequencial

Código: Selecionar todos

   ELSEIF ValType( aHash ) == "H"
      FOR EACH oElement IN aHash
            ShowJson( oElement, cTxt + '[ "' + hb_hKeyAt( aHash, oElement:__EnumIndex ) + '" ]' )
      NEXT
Acima hash, que ao invés de número é um texto, hb_hKeyAt() retorna o texto a partir do número sequencial

Vai repetindo isso até chegar no fundo do poço, até percorrer todos os níveis
isso é a recursividade que facilita.

Código: Selecionar todos


   IF ValType( aHash ) $ "NCDL" .OR. aHash == NIL
      ? cTxt, aHash
Acima é quando não tem mais o que fazer, já chegou no fundo do poço, no nível mais baixo, e o retorno é um tipo conhecido.
Não sei se pode aparecer datetime, ou outro tipo novo, aí acrescentaria nessa lista.
Caso contrário, entra no "tipo desconhecido".

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 18 Abr 2023 08:44
por malcarli
Bom dia Mestre, ficou top a função. Mas o burrão aqui não conseguiu usar a função, somente para pegar os dados, por exemplo do qsa. Poderia dar uma luz. obg

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 18 Abr 2023 13:06
por JoséQuintas
Como mostrei lá encima, ela apenas mostra o conteúdo, como seria usado no programa, e qual o retorno.
NÃO vai usar a função pra pegar nada, vai continuar tendo que fazer manualmente.

Ela faz algo do tipo:
aList := { "A", "B", "C" }
Show( aList )

aList[ 1 ] = "A"
aList[ 2 ] = "B"
aList[ 3 ] = "C"
A função mostra essa lista acima.
No fonte, vai usar a lista como base, e vai usar aList[ 1 ] ou aList[ 2 ] ou aList[ 3 ]
Com o json mesma coisa, ela só mostra como chega lá na informação.

qsa é um array, vai ter elementos 1, 2
Cada elemento desses é um hash.

qsa[1] é o primeiro qsa, mas ele se divide, usando hash
qsa[ 1 ][ "nome" ]
qsa[ 1 ][ "qual" ]

é tudo multiarray, usando número ou nome.

NÃO se complique à toa, pense no básico.

array é uma lista, hash é uma lista, JSON.... é a mesma coisa com outro nome

hb_jsondecode -> Decodificar Objeto JSON

Enviado: 18 Abr 2023 13:22
por malcarli
Consegui resolver desta forma:

Código: Selecionar todos

      nItem := 1
      cTexto:= []
      For EACH nItem IN hCnpj["qsa"]
          cTexto+= nItem["nome"] + [ - ] + nItem["qual"] + hb_OsNewLine()
      Next

Obrigado ajudou muito. Gratidão.