PDA

Ver la Versión Completa : Problemón con JSON


MaxiDucoli
23-01-2015, 18:03:30
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 (http://www.clubdelphi.com/foros/showthread.php?t=59927), 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

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:

{
"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:
"id": "file",

Esto es un array de elementos:
"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):
[
{
"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
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:


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:


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
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.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.