TransWikia.com

convertir un string en un jsonArray y obtener los valores en Delphi XE4

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.

2 Answers

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP