Arquivo

Textos com Etiquetas ‘lkjson’

Exportando dados de um DataSet para o formato JSON

25, setembro, 2009 4 comentários

Neste artigo serão demonstrados algoritmos para exportação de dados de um DataSet para o formato JSON. Até a versão 2009 do Delphi não há nada nativo para manipulação de arquivos JSON, por isso utilizei uma biblioteca Open Source chamada Delphi JSON Library (http://sourceforge.net/projects/lkjson).

O que é JSON?

JSON (JavaScript Object Notation – Notação de Objetos JavaScript) é uma formatação leve de troca de dados. Para seres humanos, é fácil de ler e escrever. Para máquinas, é fácil de interpretar e gerar. Está baseado em um subconjunto da linguagem de programação JavaScript, Standard ECMA-262 3a Edição -Dezembro – 1999. JSON é em formato texto e completamente independente de linguagem, pois usa convenções que são familiares às linguagens, incluindo C++, C#, Java, JavaScript, Perl, Python, Delphi e muitas outras. Estas propriedades fazem com que JSON seja um formato ideal de troca de dados.

JSON está constituído em duas estruturas:

•             Uma coleção de pares nome/valor. Em várias linguagens, isto é caracterizado como um object, record, struct, hash table, keyed list, ou arrays associativas;

•             Uma lista ordenada de valores. Na maioria das linguagens, isto é caracterizado como um array, vetor, lista ou sequência.

São estruturas de dados universais. Virtualmente, todas as linguagens de programação modernas as suportam, de uma forma ou de outra. É aceitável que um formato de troca de dados que seja independente de linguagem de programação se baseie nessas estruturas.

Em JSON, os dados são apresentados da seguinte forma:

Um objeto é um conjunto desordenado de pares nome/valor. Um objeto começa com { (chave de abertura) e termina com } (chave de fechamento). Cada nome é seguido por : (dois pontos) e os pares nome/valor são seguidos por , (vírgula).

Classes da biblioteca lkjson utilizadas:

TlkJSONobject: Utilizada para o cabeçalho e itens de lista do arquivo JSON;

TlkJSONlist: Utilizada para guardar a lista de valores e nomes dos fields do DataSet.

Implementação da classe manipuladora do arquivo JSON:

unit DataSetToJsonEngine;

interface

uses DB, uLkJSON;

type
  TCustomDataSetToJson = class
  private
    FJsonObjectMain : TlkJSONobject;
    FDataSet: TDataSet;
    procedure SetDataSet(const Value: TDataSet);
    procedure ValidateDataSet;
  public
    property DataSet : TDataSet read FDataSet write SetDataSet;
    constructor Create(const ADataSet : TDataSet);
    destructor Destroy; override;
    function Convert : WideString;
  end;

  TDataSetToJson = class(TCustomDataSetToJson);

implementation

uses SysUtils;

{ TCustomDataSetToJson }

function TCustomDataSetToJson.Convert: WideString;
var
  JsonList : TlkJSONlist;
  JsonDataFieldList : array of TlkJSONobject;
  I, IdxRecord : Integer;
begin
  ValidateDataSet;
  JsonList := TlkJSONlist.Create;
  try
    // Monto o cabeçalho da string Json
    FJsonObjectMain.Add('DataSetName', FDataSet.Name);
    FJsonObjectMain.Add('DataSetCount', FDataSet.RecordCount);
    with FDataSet do
    begin
      First;
      IdxRecord := 0;
      SetLength(JsonDataFieldList, FDataSet.RecordCount);
      // Adiciono os valores e nomes dos fields em uma lista
      while not EOF do
      begin
        JsonDataFieldList[IdxRecord] := TlkJSONobject.Create;
        for I := 0 to FieldCount - 1 do
          JsonDataFieldList[IdxRecord].Add(Fields[I].FieldName, Fields[i].AsString);
        JsonList.Add(JsonDataFieldList[IdxRecord]);
        Next;
        Inc(IdxRecord);
      end;
      // Atribuo a lista no objeto principal do Json
      FJsonObjectMain.Add('DataFieldList', JsonList);
      Result := TlkJSON.GenerateText(FJsonObjectMain);
    end;
  finally
    FreeAndNil(JsonList);
  end;
end;

constructor TCustomDataSetToJson.Create(const ADataSet: TDataSet);
begin
  FDataSet := ADataSet;
  FJsonObjectMain := TlkJSONobject.Create;
end;

destructor TCustomDataSetToJson.Destroy;
begin
  FJsonObjectMain.Free;
  inherited;
end;

procedure TCustomDataSetToJson.SetDataSet(const Value: TDataSet);
begin
  FDataSet := Value;
end;

procedure TCustomDataSetToJson.ValidateDataSet;
begin
  if FDataSet = nil then
    raise Exception.Create('DataSet não atribuído');
  FDataSet.Active := not(FDataSet.Active);
  if FDataSet.IsEmpty then
    raise Exception.Create('DataSet vazio');
end;

end.

Consumindo a classe manipuladora:

Criar um novo form, adicione um botão e um MEMO. No evento OnClick do botão adicione o seguinte código:

procedure TfrmDataSetToJsonMain.Button1Click(Sender: TObject);
var
  JsonEngine : TDataSetToJson;
begin
  JsonEngine := TDataSetToJson.Create(SQLQuery1);
  Memo1.Text := JsonEngine.Convert;
end;

Testando o arquivo JSON gerado:

Neste exemplo o arquivo JSON foi gerando dentro de um campo MEMO, o texto nele contido poderá ser testado em uma ferramenta web, segue link: http://www.thomasfrank.se/downloadableJS/JSONeditor_example.html

Testando arquivo JSON

Testando arquivo JSON

Fontes – Delphi 2009

Os dados exportados nesse exemplo está no banco de dados de exemplo do Firebird 2.1. Utilizei uma conexão DBExpress com o driver da Embarcadero http://groups.google.com/group/dbxfirebird

Este é um pequeno exemplo de como criar arquivos JSON de forma rápida e fácil. No próximo artigo teremos um exemplo de como trocar arquivos JSON via socket com uma aplicação JavaScript.