Página 1 de 2

função HScan() para hash table

Enviado: 28 Out 2019 16:22
por cMach
Olá Pessoal,
Estou tentando localizar um valor em um json usando a função hScan mas não retorna positivo, mesmo quando o valor existe no arquivo. Alguém tem alguma dica?
Ex:

Código: Selecionar todos

local obj     
local htable := hash()
...
hb_jsonDecode(obj:ResponseBody, @htable)

if ( HScan( htable, "[b]Lote processado com sucesso[/b]."))
   ? "Registro localizado"
endif   

...
json:

Código: Selecionar todos

{
    "message": "Evento retornado",
    "data": {
        "ocorrencias": [],
        "eventos": [
            {
                "evtTest": {
                    "ideEvento": {
                    },
                    "ideEvento2": {
                    },
                            }
                        }
                },
                "status": {
                    "codigo": "xxx",
                    "mensagem": "evento inválido."
                },
        "status_consulta": {
            "mensagem": "[b]Lote processado com sucesso[/b]."
        },
        ]
    }
}

função HScan() para hash table

Enviado: 29 Out 2019 16:34
por Vlademiro
O Json está mal formado.

Fiz um teste usando o harbour 3.4 e ele não conseguiu ler o Json

Código: Selecionar todos


#xtranslate text into <v> [<rst:reset>]   => #pragma __text|<v>+=%s;if(<.rst.>,<v>:="",)

PROCEDURE Main

    local cJson, hTable

    TEXT INTO cJson RESET
{
    "message": "Evento retornado",
    "data": {
        "ocorrencias": [],
        "eventos": [
            {
                "evtTest": {
                    "ideEvento": {
                    },
                    "ideEvento2": {
                    },
                            }
                        }
                },
                "status": {
                    "codigo": "xxx",
                    "mensagem": "evento inválido."
                },
        "status_consulta": {
            "mensagem": "[b]Lote processado com sucesso[/b]."
        },
        ]
    }
}


    ENDTEXT
    ? cJson

    htable := hb_jsonDecode( cjson )

    ? hb_ValToExp( hTable )
    ? HScan( hTable , "[b]Lote processado com sucesso[/b]." )  // HSCan retorna um numero


    RETURN
Outra coisa. No Harbour 3.4 (com a lib xhb.hbc) o retorno de HScan é um número, não um valor lógico

Dica: testa o Json em https://jsonformatter.org/json-parser

função HScan() para hash table

Enviado: 30 Out 2019 13:16
por bencz
HUmm... isso não me faz muito sentido... SE realmente o sistema consegue decodificar o Json e inserir dentro de um HASH Table, provavelmente ele vai ter apenas as chaves, não ?
Pois uma estrutura HASH não consegue possuir valores duplicados...

Veja este exemplo: viewtopic.php?f=46&t=18781#p119665

função HScan() para hash table

Enviado: 30 Out 2019 18:42
por asimoes
Exemplo de uso:

Código: Selecionar todos

nRec      := Hb_HScan( ::hConcessionarias, {| nKey, cChave | cChave["CODEFEBRABAN"] = oElemento["CODCON"] } )

função HScan() para hash table

Enviado: 30 Out 2019 21:22
por JoséQuintas
Ainda não entendo nada disso, mas....
Se json vira array....

Código: Selecionar todos

IF aVar[ "data" ] [ "status_consulta" ] [ "mensagem" ] == "[b]Lote processado com sucesso[/b]"
   ? "sei lá se tá certo"
ENDIF

função HScan() para hash table

Enviado: 31 Out 2019 00:11
por JoséQuintas
É.... exatamente o que eu pensava....

Código: Selecionar todos

{
    "glossary": {
        "title": "example glossary",
		"GlossDiv": {
            "title": "S",
			"GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
					"SortAs": "SGML",
					"GlossTerm": "Standard Generalized Markup Language",
					"Acronym": "SGML",
					"Abbrev": "ISO 8879:1986",
					"GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
						"GlossSeeAlso": ["GML", "XML"]
                    },
					"GlossSee": "markup"
                }
            }
        }
    }
}

Código: Selecionar todos

PROCEDURE Main

   LOCAL hTable := hb_Hash()

   SetMode( 25, 80 )
   CLS
   hb_JsonDecode( MemoRead( "test.txt" ), @hTable )
   ? Len( hTable )
   ? hTable[ "glossary" ] [ "title" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "title" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "ID" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "SortAs" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "GlossTerm" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "Acronym" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "Abbrev" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "GlossDef" ] [ "para" ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "GlossDef" ] [ "GlossSeeAlso" ] [ 1 ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "GlossDef" ] [ "GlossSeeAlso" ] [ 2 ]
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "GlossSee" ]
   Inkey(0)

   RETURN
json.png

função HScan() para hash table

Enviado: 31 Out 2019 00:19
por JoséQuintas
Pequena descrição:

Variável HASH é igual variável array, com a diferença de que ao invés de número, se usa um texto.

a[ 1 ], a[ 2 ], a[ 3 ] vira a[ "primeiro" ], a[ "segundo" ], a[ "terceiro" ]

E.... array pode ser multidimensional, seja hash ou não.

O formato json nada mais é do que o array (hash) representado em forma de texto.

chaves {} representam divisão em arrays identificados por nome (hash)
colchetes [] representam divisão em arrays identificados por número
"nome": representa o nome que identifica o elemento do array

Não gostei.
Pode economizar bytes pro computador, mas confunde.
XML é mais interessante.

função HScan() para hash table

Enviado: 31 Out 2019 13:59
por cMach
Concordo, é meio trabalhoso.
Existe uma serie de funções no harbour para facilitar a manipulação da hash table, a exemplo do "HHasKey" que verifica se uma determinada chave existe ou não no array, mas de qq forma precisa informar o endereço dela. O HScan, que ainda não me foi util por não ter conseguido usar adequadamente, mas pelo que entendo dele, deveria procurar por um valor informado, sem a necessidade de colocar o endereço do array. Ou seja, preciso saber se no json tem um campo chamado "protocolo" mas não sei onde ele pode estar. Neste caso, acho que o HScan seria util.
Obg

função HScan() para hash table

Enviado: 31 Out 2019 14:22
por cMach
Qualquer informação que eu procure usando o Hscan retorna 0, mesmo que a informações esteja no json...

função HScan() para hash table

Enviado: 31 Out 2019 15:03
por JoséQuintas
cMach escreveu:Qualquer informação que eu procure usando o Hscan retorna 0, mesmo que a informações esteja no json...
Se HSCan é o equivalente de AScan.... então não vai procurar em sub-arrays, somente no array principal.

função HScan() para hash table

Enviado: 31 Out 2019 16:14
por cMach
Faz sentido José Quintas... infelizmente sendo assim não adiantaria muito.
obg pela atenção.

função HScan() para hash table

Enviado: 31 Out 2019 17:28
por JoséQuintas
JoséQuintas escreveu:Se HSCan é o equivalente de AScan.... então não vai procurar em sub-arrays, somente no array principal.
Na prática é pior que isso. HSCAN realmente é igual a ASCAN, mas isso procura nos valores e não nos IDs....

Não sei se tem outro jeito, mas assim foi:

Código: Selecionar todos

PROCEDURE Main

   LOCAL hTable := hb_Hash()

   SetMode( 25, 80 )
   CLS
   hb_JsonDecode( MemoRead( "test.txt" ), @hTable )
   ? hTable[ "glossary" ] [ "GlossDiv" ] [ "GlossList" ] [ "GlossEntry" ] [ "GlossDef" ] [ "para" ]
   ? PesquisaHash( hTable, "para" )

   Inkey(0)

   RETURN

STATIC FUNCTION PesquisaHash( hTable, cTexto )

   LOCAL oElement, xValue := ""

   IF hb_HHasKey( hTable, cTexto )
      RETURN hTable[ cTexto ]
   ENDIF
   FOR EACH oElement IN hTable
      IF ValType( oElement ) == "H"
         xValue := PesquisaHash( oElement, cTexto )
         IF ! Empty( xValue )
            EXIT
         ENDIF
      ENDIF
   NEXT

   RETURN xValue
hash.png
Pensei como array:
Pesquisa no atual, se não tem, vê nos subelementos que forem hash, e assim por diante até encontrar.

função HScan() para hash table

Enviado: 31 Out 2019 20:16
por asimoes
No meu teste hb_HScan funciona, o teste abaixo retorna 2

Código: Selecionar todos

  hTable  := {=>}
   
   hRecord := {=>}
   hRecord["CODIGO"] := "001"
   Hb_HSet(hTable, "1", hRecord)
   
   hRecord := {=>}
   hRecord["CODIGO"] := "002"
   Hb_HSet(hTable, "2", hRecord)
   
   hRecord := {=>}
   hRecord["CODIGO"] := "003"
   Hb_HSet(hTable, "3", hRecord)
   
   cJSON := Hb_JSONEncode( hTable, .T.)
   
   nPos := hb_HScan( hTable, {| nKey, cChave | cChave["CODIGO"] = "002"} )
   
   Hb_MemoWrit( "JSON.JSON", cJSON )
 
   cJSON := MemoRead( "JSON.JSON" ) //Leitura do JSON
   
   nLen := hb_jsonDecode( cJSON, @hTable )
   
   nPos := hb_HScan( hTable, {| nKey, cChave | cChave["CODIGO"] = "002"} )

função HScan() para hash table

Enviado: 31 Out 2019 20:28
por asimoes
Mais registros

Código: Selecionar todos

  hTable  := {=>}
   
   FOR nInt := 1 TO 100
      hRecord := {=>}
      hRecord["CODIGO"] := StrZero(nInt,3)
      Hb_HSet(hTable, Hb_NtoS(nInt), hRecord)
   NEXT
   
   cJSON := Hb_JSONEncode( hTable, .T.)
   
   nPos := hb_HScan( hTable, {| nKey, cChave | cChave["CODIGO"] = "015"} )
   
   Hb_MemoWrit( "JSON.JSON", cJSON )

   cJSON := MemoRead( "JSON.JSON" ) //Leitura do JSON
   
   hTable := Nil
   
   nLen := hb_jsonDecode( cJSON, @hTable )
   
   nPos := hb_HScan( hTable, {| nKey, cChave | cChave["CODIGO"] = "030"} )

função HScan() para hash table

Enviado: 31 Out 2019 20:38
por asimoes
Mostra o JSON para testar, deve ser bobeira