Stack Overflow en español Asked by hugo fernandez on August 26, 2021
una aplicación cliente me envía el siguiente string:
{"tabla":"programacxp","opcion":"1","data":[{"fechapago":"2020-07-17","semana":29,"concepto":"RECOLECCION DE BASURA ","proyecto":"7E313-C2732","importe":"100.00","proved":"DDF","status":true,"clasif":"GASTO DE ADMON","periodo":"0","dias":"5","aplicado":false}]},
Mi pregunta es: ¿Cómo puedo extraer los valores tabla
y opcion
y crear un array con el objeto data
, para manipular esta información en Delphi XE?
El cliente me envía
modDb(jsonquery){
let query = JSON.stringify(jsonquery);
let consulta = this.locUrl+'updDb/('+query+')';
return this._http.get(consulta).pipe(map(res =>res));
haciendo debug en mi Aplicación Delphi, los datos llegan sin problema
{"tabla":"programacxp","opcion":"1","data":[{"fechapago":"2020-07-17","semana":29,"concepto":"RECOLECCION DE BASURA ","proyecto":"7E313-C2732","importe":"100.00","proved":"DDF","status":true,"clasif":"GASTO DE ADMON","periodo":"0","dias":"5","aplicado":false}]}
Ahora mi problema es como manipularlos.
Gracias de nuevo por su valiosa ayuda.
Finalmente, logré obtener la información con este código:
function TServerMethods1.updDb(datos: string): string;
var
nomTabla, DataStr, fieldStr, parStr, nomfield, mensaje: string;
j, x, opc, lenStr, lenTag: integer;
LJsonObj, DataObj: TJSONObject;
jsPairTabla, jsPairOpcion, jsPairData: TjsonPair;
jsonData, jsOpcion, PairValue: TJSONValue;
currTable: TADTable;
AField: array [0 .. 20] of array [0 .. 1] of string;
fs: TFormatSettings;
currField: tField;
begin
// jsonString := datos; // solo para debuguear....
LJsonObj := TJSONObject.ParseJSONValue(datos) as TJSONObject;
try
jsonData := LJsonObj.Get('tabla').JsonValue;
jsPairTabla := TjsonPair(jsonData);
nomTabla := jsPairTabla.jsonString.ToString;
jsOpcion := LJsonObj.Get('opcion').JsonValue;
jsPairOpcion := TjsonPair(jsOpcion);
opc := StrToInt(jsPairOpcion.jsonString.ToString);
DataStr := LJsonObj.Get('data').JsonValue.ToString;
lenStr := Length(DataStr) - 2;
fieldStr := DataStr.Substring(1, lenStr);
DataObj := TJSONObject.ParseJSONValue(fieldStr) as TJSONObject;
PairValue := TJSONValue.Create;
for j := 0 to DataObj.Size - 1 do
begin
PairValue := DataObj.Get(j).JsonValue;
parStr := DataObj.Get(j).ToString;
jsPairData := TjsonPair(PairValue);
lenTag := Ansipos('":', parStr);
AField[j, 0] := copy(parStr, 1, lenTag);
if pos('":true', parStr) > 0 then
AField[j, 1] := 'true'
else if pos('":false', parStr) > 0 then
AField[j, 1] := 'false'
else
AField[j, 1] := jsPairData.jsonString.ToString;
end;
finally
currTable := TADTable.Create(self);
currTable := programaCxp;
// aquí proceso la información
//
end;
end;
Obviamente no es la solución optima, pero tanto JsonVAlue.value, como JsonString.value, para obtener el nombre y el valor del par no funcionan en XE4, Saludos
Answered by hugo fernandez on August 26, 2021
Puedes valerte del soporte estándar de Delphi para JSON, que se encuentra en las unidades System.JSON
.
Lo básico es parsear el string que obtienes en un objeto de tipo TJSONValue
, del que puedes ya extraer los valores mediante el método GetValue
.
Te muestro primero un ejemplo simple (sin encargarnos aún del arreglo):
uses
System.JSON;
procedure TForm3.Button1Click(Sender: TObject);
var
sJSON: string;
Datos: TJSONValue;
Tabla: string;
Opcion: Integer;
begin
{ la cadena con el JSON de tu pregunta }
sJSON := '{"tabla":"programacxp","opcion":"1","data":[{"fechapago":"2020-07-17"'
+ ',"semana":29,"concepto":"RECOLECCION DE BASURA ","proyecto":"7E313-C2732"'
+ ',"importe":"100.00","proved":"DDF","status":true,"clasif":"GASTO DE ADMON"'
+ ',"periodo":"0","dias":"5","aplicado":false}]}';
{ _conversión_ de la cadena en un TJSONValue }
Datos := TJSonObject.ParseJSONValue(sJSON);
{ extracción de datos en variables de distintos tipos }
Tabla := Datos.GetValue<string>('tabla');
Opcion := Datos.GetValue<Integer>('opcion');
{ Mostrar datos al usuario }
ShowMessage(Format(''
+ 'Tabla: %s'#13
+ 'Opcion: %d'
, [Tabla, Opcion]));
end;
El arreglo lo podemos manejar de varias formas, una es valiéndonos del tipo TJSONArray
, lo que nos permite iterar por el arreglo y tratar a cada uno de sus elementos como un TJSONValue
.
Básicamente algo como:
var
...
DatosData: TJSONArray;
DataElemento: TJSONValue;
begin
...
{ obtenemos el arreglo 'data' en el objeto DatosData, de tipo TJSONArray }
DatosData := Datos.GetValue<TJSONArray>('data');
for DataElemento in DatosData do
begin
{ acá puedes utilizar DataElemento.GetValue para extraer los datos de cada elemento }
end;
Poniendo todo en conjunto, podríamos agregar los datos de todos los elementos del arreglo al mensaje mostrado al usuario del primer ejemplo así:
procedure TForm3.Button1Click(Sender: TObject);
var
sJSON: string;
Datos: TJSONValue;
Tabla: string;
Opcion: Integer;
DatosData: TJSONArray;
DataElemento: TJSONValue;
sData: string;
Contador: Integer;
begin
sJSON := '{"tabla":"programacxp","opcion":"1","data":[{"fechapago":"2020-07-17"'
+ ',"semana":29,"concepto":"RECOLECCION DE BASURA ","proyecto":"7E313-C2732"'
+ ',"importe":"100.00","proved":"DDF","status":true,"clasif":"GASTO DE ADMON"'
+ ',"periodo":"0","dias":"5","aplicado":false}]}';
Datos := TJSonObject.ParseJSONValue(sJSON);
Tabla := Datos.GetValue<string>('tabla');
Opcion := Datos.GetValue<Integer>('opcion');
DatosData := Datos.GetValue<TJSONArray>('data');
sData := '';
Contador := 0;
for DataElemento in DatosData do
begin
sData := sData + Format(''
+ ' Elemento # %d '#13
+ ' FechaPago: %s'#13
+ ' Semana: %d'#13
+ ' Proyecto: %s'#13
, [ Contador
, DateToStr(DataElemento.GetValue<TDate>('fechapago'))
, DataElemento.GetValue<Integer>('semana')
, DataElemento.GetValue<string>('proyecto')
]);
Inc(Contador);
end;
ShowMessage(Format(''
+ 'Tabla: %s'#13
+ 'Opcion: %d'#13
+ 'Data:'#13
+ '%s'
, [Tabla, Opcion, sData]));
end;
Otra forma de obtener los datos es indicar la ruta completa en el método GetData
sobre el TJSONValue
que contiene todo el objeto, por ejemplo:
var
...
FechaPago: TDate;
begin
...
FechaPago := Datos.GetValue<TDate>('data[0].fechapago');
ShowMessage(DateToStr(FechaPago));
end;
Para finalizar mencionar que hay otras bibliotecas que ofrecen soporte para procesar JSON, en lo personal trato de utilizar la RTL, pues el código es más estándar y tiene menos dependencias, pero al final puede haber alguna buena razón para utilizar una biblioteca de terceros y tampoco hay que cerrarse a la idea.
Answered by jachguate on August 26, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP