Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Problemón con JSON (https://www.clubdelphi.com/foros/showthread.php?t=87566)

MaxiDucoli 23-01-2015 18:03:30

Problemón con JSON
 
Buenas tardes, quería saber si me pueden ayudar con este problema que tengo.
No sé como hacer para separar los datos estos que tengo acá con JSON.

[{"jsonrpc":"2.0","id":3,"result":[{"userId":1986698431,"externalUserId":"100001529474550","name":"José Pérez","firstName":"José","pic":"https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xpa1/v/t1.0-1/p50x50/10947221_865347666859541_63918475058584938.jpg?oh\u003d8a2e5db6442badcd49572e49b257ac9e\u0026oe\u003 d552D391D\u0026__gda__\u003d1432112641_0c2311f178961cbb9ea57c4c792d1de6","pic100":"https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xpa1/v/t1.0-1/p50x50/10947221_865347666859541_63918475058584938.jpg?oh\u003d8a2e5db6442badcd49572e49b257ac9e\u0026oe\u003 d552D391D\u0026__gda__\u003d1432112641_0c2311f178961cbb9ea57c4c792d1de6","country":"US","langCode":" es_ES","lastSignInTime":1421802990,"friendType":"NETWORKED","pictureUrls":[]}]

Intenté con SuperObject, pero no entiendo nada.

Alguien me puede decir como hacer por favor??

Muchas gracias.

Neftali [Germán.Estévez] 27-01-2015 10:53:10

No explicas qué problema tienes con el "parseo".
Si te da errores o es que no saber hacerlo.

Yo he probado a hacerlo con la librería uLKJSOn, de la que otras veces hemos hablado en los foros y a priori he podido obtener datos.
Eso sí, este texto tiene algunos problemas.
Por un lado no es correcto a nivel de elementos (no "cuadran" los elementos { } [ ]).

Por otro lado me están dando problemas los campos pic por los valores almacenados (la dirección https). deberías investigarlo.

Si revisas este hilo, por ejemplo, con ese código de ejemplo se puede "parsear" el texto a excepción de los elementos que te he comentado.

MaxiDucoli 27-01-2015 22:08:28

No. La verdad es que esto supera mi entender....
Soy medio duro cuando no le capto la onda a algo.

Me explicás por favor esto:

"jsonrpc": "2.0", ---------- ESTO ES UN DATO
"id": 3, ---------- ESTE ES OTRO DATO
"result": [{ ----------- Y ESTO SERIA UN ARRAY DE DATOS????

Yo necesito que me devuelva el valor de name. Y no sé como sacarlo. Me da error 0x0000000C en las uLKJSON y es obvio que es mi problema, por que no entiendo para nada el JSON por más que lea y lea en cualquier lado por internet.

Te paso a mostrar como lo estoy haciendo mal

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var
 JSON: TlkJSONobject;
  UnObjetoJSON: TlkJSONobject;
  UnArrayJSON,
  OtroArrayJSON: TlkJSONlist;
begin

   JSON:=TlkJSONobject.Create;
  try
    // parseamos el JSON
    JSON:=TlkJSON.ParseText(memo2.Text) as TlkJSONobject;

    UnArrayJSON:=JSON.Field['resul'] as TlkJSONlist;

    for n:=0 to UnArrayJSON.Count - 1 do
        begin
          // ...
          memo2.Text := UnArrayJSON.Child[n].Field['name'].Value;
        end;
  finally
    JSON.Free;
  end;



end;

La verdad es que no entiendo nada.
Gracias.

Neftali [Germán.Estévez] 27-01-2015 22:22:10

Simplificando mucho, podemos decir que en un JSON tienes elementos simples, objetos y arrays.

En un ejemplo como este:

Código:

{
  "menu": {
    "id": "file",
    "value": "File",
    "popup": {
      "menuitem": [
        {
          "value": "New",
          "onclick": "CreateNewDoc()"
        },
        {
          "value": "Open",
          "onclick": "OpenDoc()"
        },
        {
          "value": "Close",
          "onclick": "CloseDoc()"
        }
      ]
    }
  }
}

Esto podría ser un elemento simple:
Código:

"id": "file",
Esto es un array de elementos:
Código:

"menuitem": [
        {
          "value": "New",
          "onclick": "CreateNewDoc()"
        },
        {
          "value": "Open",
          "onclick": "OpenDoc()"
        },
        {
          "value": "Close",
          "onclick": "CloseDoc()"
        }
      ]

Y el elemento menu sería un objeto.

Los objetos y los array pueden contener a su vez objetos, arrays o elementos simples.

Neftali [Germán.Estévez] 27-01-2015 22:26:27

Como creo que te comenté antes, el texto que has colocado, es incorrecto o está incompleto (empecemos por ahí).

Si lo formateamos correctamente (http://jsonviewer.stack.hu/) obtenemos esto (he abreviado las URL's para que se vea menjor):
Código:

[
  {
    "jsonrpc": "2.0",
    "id": 3,
    "result":[
      {
        "userId": 1986698431,
        "externalUserId": "100001529474550",
        "name": "José Pérez",
        "firstName": "José",
        "pic": "https://fbcdn-profile-a.akamaihd...6",
        "pic100": "https://fbcdn-profile-a.akamaihd....",
        "country": "US",
        "langCode": " es_ES",
        "lastSignInTime": 1421802990,
        "friendType": "NETWORKED",
        "pictureUrls": [
         
        ]
      }
    ]

Creo que el inicio no es correcto y además parece incompleto.
¿Realmente ese texto es el completo con el que estás trabajando?

MaxiDucoli 27-01-2015 22:50:58

1 Archivos Adjunto(s)
El texto completo es muy largo, igual lo coloco.
Pero el JSON me da nil cuando pongo:

Hago una variable llamada nombre : string y cargo el contenido de un memo en esa variable (seria el texto completo del fondo) y lo trato de cargar de la siguiente manera:


Código Delphi [-]
var
 JSON: TlkJSONobject;
  UnObjetoJSON: TlkJSONobject;
  UnArrayJSON,
  OtroArrayJSON: TlkJSONlist;
begin

   JSON:=TlkJSONobject.Create;
  try
    // parseamos el JSON
    JSON:=TlkJSON.ParseText(memo2.Text) as TlkJSONobject;

    UnArrayJSON:=JSON.Field['resul'] as TlkJSONlist;

    for n:=0 to UnArrayJSON.Count - 1 do
        begin
          // ...
          memo2.Text := UnArrayJSON.Child[n].Field['name'].Value;
        end;
  finally
    JSON.Free;
  end;


Cuando voy a debugger, JSON me sale con valor NIL- Por lo que entiendo no está cargando el strin en ParseText.
Es así??






El texto esta adjunto por que me paso de los 2000 caracateres.

Neftali [Germán.Estévez] 28-01-2015 17:29:33

Vale.
Ya se dónde estaba el proble y porqué estaba dando error.

El problema (y yo no me había fijado) es que el texto completo empieza por un [.
Eso quiere decir que lo primero que hay ya es un array de elementos.

Visto eso, el parseo es sencillo. este código, te extrae todos los nombres a una lista:

Código Delphi [-]
var
  objResp, obj:TlkJSONobject;
  str:string;
  objResult:TlkJSONlist;
  i,j:Integer;
  b:boolean;
begin
  // Crear el objeto base
  objResp := TlkJSONobject.Create();
  try
    // Parsear el texto completo JSON (está en un memo)
    TlkJSONbase(objResp) := TlkJSON.ParseText(Memo1.Text);
    // Obtener el contenido del primer elemento ya que el raiz está dentro de [ ]
    TlkJSONbase(objResp) := objResp.Child[0];

    // Campos iniciales
    b  := objResp.Field['jsonrpc'].Value;
    i  := objResp.Field['id'].Value;
    // Obtener el objeto result
    TlkJSONBase(objResult) :=  objResp.Field['result'];
    // Lista de resultados
    for i := 0 to (objResult.Count - 1) do begin
      // Obtener un objeto de la llista
      TlkJSONBase(obj) := objResult.Child[i];
      
      // Datos de Result
      //...
      Str := obj.Field['name'].Value;
      //...
      
      // Añadirlo a la lista
      ListBox1.Items.Add(Str);
    end;
  finally
    // control de errores
  end;
end;

Con esto recorres el JSON y rellenas un ListBox con los nombres que hay en el campo "name".

Un saludo.

pnsd_89 25-09-2015 17:54:39

:cool: Que bueno El poder haber encontrado este post. Me ha sido de gran Ayuda.
Tenia el mismo Problema no sabia ni entendía la estructura JSON y mucho menos sabia como realizar la lectura de uno en Delphi. Muchisimas gracias Neftali uno de mis grandes maestros de Delphi(desde 2007 a través de este foro :) ).

Luego de haber dicho esto quisiera presentar un problema, la lectura de mi JSON lo e podido realizar sin problema alguno, pero al igual que al archivo JSON de ejemplo adjunto por ustedes. Mi archivo también tiene un Array de objetos osea que comienza de y termina todo el archivo de esta manera [].

Al codigo de facilito Neftali le he agregado un ciclo para asi poder recorrer todos mis objetos
Código Delphi [-]
objResp := TlkJSONobject.Create();
  try
    // Parsear el texto completo JSON (está en un memo)
    TlkJSONbase(objResp) := TlkJSON.ParseText(Memo1.Text);
    // Obtener el contenido del primer elemento ya que el raiz está dentro de [ ]
   for i := 0 to (objResp.Count - 1) do
    begin    
       TlkJSONbase(objResp) := objResp.Child[i];
    ...
    ...
    ...

La primera vez que hace la pasada osea cuando i = 0 la captura de los datos me hace perfectamente, pero cuando pasa por segunda vez osea que i = 1 el valor inicial b (solo que en mi caso b es string y no boolean) no captura y me dispara una misterioso y siniestro error de acces violation.
Que estoy haciendo mal? Tengo que liberar el objeto objResp....................:eek::eek:qP:-)qP:-)
Soy un reverendo idiota jajajaja al terminar de escribir esta pregunta me he auto respondido jajajaja
Me voy a auto responder para que si alguno tiene el mismo problema lo resuelva. El código de neftali hace lo siguiente.
Código Delphi [-]
TlkJSONbase(objResp) := objResp.Child[0];
Lo que hace que objResp se convierta en un objeto unico y pierda los datos de los demas indices del arreglo por ende cuando busca ese indice en esa variable de tipo objeto ya no la encuentra y lanza el error de memoria XD XD XD enserio me causa mucha gracia estar respondiendome yo solo por que hace ya unas cuantas horas que pierdo tratando de resolverlo y creo que escribir el problema me ayudo a pensar bien en la solucion. jajaja Saludos :D
Lo que hare es declarar otra variable de tipo objeto para seguir manteniendo los valores en los indices de objResp.


La franja horaria es GMT +2. Ahora son las 16:40:11.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi