Ciao ragazzi, una domanda scema, qual'è il modo più veloce di recuperare i dati da questo formato
{
"personaggi" : [
{
"val1" : "pippo",
"val2" : "2014-11-18T10:25:38.486320Z",
"val3" : 1,
"val4" : 2
},
{
"val1" : "pluto",
"val2" : "2014-11-18T10:25:38.486320Z",
"val3" : 1,
"val4" : 2
},
{
"val1" : "minni",
"val2" : "2014-11-18T10:25:38.486320Z",
"val3" : 1,
"val4" : 2
}
]
}
Si è JSon.
E FreePascal ha le sue librerie.
fpjson: per la struttura degli oggetti letti dal json
jsonparser: per leggerli.
più veloce?
procedure TJSonDataProcessor.ParseFile;
var
Parser: TJSONParser;
FS: TFileStream;
begin
try
try
FS := TFileStream.Create(FileName, fmOpenRead);
except
on E: Exception do
begin
FLogger.Error(E.Message);
end;
end;
if assigned(fs) then
begin
Parser := TJSONParser.Create(fs);
FJSonRoot := Parser.Parse;
end;
finally
FreeAndNil(Parser);
FreeAndNil(FS);
end;
end;
Abbastranza veloce?
procedure TSectionProcessor.ProcessSection(JSonSection: TJSONObject);
var
Value: TJSONData;
begin
Value := JSonSection.Find('text');
if assigned(Value) then
begin
Value.AsString := doTranslate(Value.AsString);
sleep(random(10));
end;
Value := JSonSection.Find('name');
if assigned(Value) then
begin
Value.AsString := doTranslate(Value.AsString);
sleep(random(10));
end;
Value := JSonSection.Find('alignment');
if assigned(Value) then
begin
Value.Value := doTranslate(Value.AsString);
sleep(random(10));
end;
Value := JSonSection.Find('description');
if assigned(Value) then
begin
Value.AsString := doTranslate(Value.AsString);
sleep(random(10));
end;
Value := JSonSection.Find('sections');
if (assigned(Value)) then
begin
if (Value.JSONType = jtArray) then
ProcessSections(Value as TJSONArray)
else if (Value.JSONType = jtObject) then
ProcessSection(Value as TJSONObject);
end;
end;
Per leggere in modo "selettivo" i nodi.
Alla fine è un albero quello che vai a navigare.
Spero di averti dato qualche dritta utile ;)
Stilgar
Grazie proverò, perchè io avevo provato con la guida scritta da Nomorelogic
ma ho questi errori:
superobject.pas(122,18) Error: No matching implementation for interface method "IUnknown.QueryInterface(constref TGuid,out <Formal type>):LongInt; CDecl;" found
superobject.pas(122,18) Error: No matching implementation for interface method "IUnknown._AddRef:LongInt; CDecl;" found
superobject.pas(122,18) Error: No matching implementation for interface method "IUnknown._Release:LongInt; CDecl;" found
superobject.pas(811,1) Fatal: There were 3 errors compiling module, stopping
Allora, l'idea del json è quella di un albero.
Quando fai il parse ottieni la root.
IJsONVisitor = interface
['{547B45C9-1EF1-4E5F-9223-E2B9031AC7A8}']
procedure visit(Value: TJSONData);
procedure visitIntegerNumber(Value: TJSONIntegerNumber);
procedure visitInt64Number(Value: TJSONInt64Number);
procedure visitFloatNumber(Value: TJSONFloatNumber);
procedure visitString(Value: TJSONString);
procedure visitBoolean(Value: TJSONBoolean);
procedure visitNull(Value: TJSONNull);
procedure visitArray(Value: TJSONArray);
procedure visitObject(Value: TJSONObject);
end;
{ TJSonDataProcessor }
TJSonDataProcessor = class(TAbstractProcessor, IJsONVisitor)
private
FFileName: string;
procedure SetFileName(AValue: string);
protected
FJSonRoot: TJSONData;
protected
procedure visit(Value: TJSONData); virtual;
procedure visitIntegerNumber(Value: TJSONIntegerNumber); virtual;
procedure visitInt64Number(Value: TJSONInt64Number); virtual;
procedure visitFloatNumber(Value: TJSONFloatNumber); virtual;
procedure visitString(Value: TJSONString); virtual;
procedure visitBoolean(Value: TJSONBoolean); virtual;
procedure visitNull(Value: TJSONNull); virtual;
procedure visitArray(Value: TJSONArray); virtual;
procedure visitObject(Value: TJSONObject); virtual;
public
procedure ParseFile;
procedure SaveFile;
property FileName: string read FFileName write SetFileName;
public
procedure process; virtual; abstract;
end;
{ TJSonDataProcessor }
procedure TJSonDataProcessor.SetFileName(AValue: string);
begin
if FFileName = AValue then
Exit;
FFileName := AValue;
end;
procedure TJSonDataProcessor.visit(Value: TJSONData);
begin
case Value.JSONType of
jtArray: visitArray(Value as TJSONArray);
jtBoolean: visitBoolean(Value as TJSONBoolean);
jtNull: visitNull(Value as TJSONNull);
jtObject: visitObject(Value as TJSONObject);
jtNumber:
begin
case (Value as TJSONNumber).NumberType of
ntFloat:
visitFloatNumber(Value as TJSONFloatNumber);
ntInteger:
visitIntegerNumber(Value as TJSONIntegerNumber);
ntInt64:
visitInt64Number(Value as TJSONInt64Number);
else
raise EInvalidCast.Create('Number type not recognized');
end;
end;
jtString: visitString(Value as TJSONString);
end;
end;
procedure TJSonDataProcessor.visitIntegerNumber(Value: TJSONIntegerNumber);
begin
end;
procedure TJSonDataProcessor.visitInt64Number(Value: TJSONInt64Number);
begin
end;
procedure TJSonDataProcessor.visitFloatNumber(Value: TJSONFloatNumber);
begin
end;
procedure TJSonDataProcessor.visitString(Value: TJSONString);
begin
end;
procedure TJSonDataProcessor.visitBoolean(Value: TJSONBoolean);
begin
end;
procedure TJSonDataProcessor.visitNull(Value: TJSONNull);
begin
end;
procedure TJSonDataProcessor.visitArray(Value: TJSONArray);
var
idx: integer;
begin
for idx := 0 to Value.Count - 1 do
begin
visit(Value.Items[idx]);
end;
end;
procedure TJSonDataProcessor.visitObject(Value: TJSONObject);
begin
end;
procedure TJSonDataProcessor.ParseFile;
var
Parser: TJSONParser;
FS: TFileStream;
begin
try
try
FS := TFileStream.Create(FileName, fmOpenRead);
except
on E: Exception do
begin
FLogger.Error(E.Message);
end;
end;
if assigned(fs) then
begin
Parser := TJSONParser.Create(fs);
FJSonRoot := Parser.Parse;
end;
finally
FreeAndNil(Parser);
FreeAndNil(FS);
end;
end;
procedure TJSonDataProcessor.SaveFile;
var
newFileName, originalFileName: string;
FS: TFileStream;
pretty: TJSONPrettyPrinter;
begin
originalFileName := FFileName;
//newFileName := ExpandFileName(originalFileName);
//newFileName := Copy(newFileName, 1, Length(newFileName) - length('.json')) + '.en.json';
//RenameFile(FFileName, newFileName);
newFileName := ExpandFileName(originalFileName);
newFileName := Copy(newFileName, 1, Length(newFileName) - length('.json')) + '.it.json';
FS := TFileStream.Create(newFileName, fmCreate);
pretty := TJSONPrettyPrinter.Create;
pretty.Target := FS;
pretty.print(FJSonRoot);
FreeAndNil(pretty);
end;
{ TStructureProcessor }
TStructureProcessor = class(TJSonDataProcessor)
protected
procedure ProcessFile(aName: TJSONStringType);
procedure ProcessChildren(value: TJSONObject);
procedure ProcessChildrens(JSonSection: TJSONArray);
procedure visitObject(Value: TJSONObject); override;
public
procedure process; virtual;
end;
{ TStructureProcessor }
procedure TStructureProcessor.ProcessFile(aName: TJSONStringType);
var
p: TDataProcessor;
targetFileName: string;
begin
p := TDataProcessor.Create;
targetFileName := ExpandFileName(ExtractFileDir(ExpandFileName(FileName)) + PathDelim + aName);
p.FileName := targetFileName;
P.LangSource := self.LangSource;
P.LangTarget := self.LangTarget;
FLogger.Info('Process file '+targetFileName);
p.process;
FreeAndNil(p);
end;
procedure TStructureProcessor.ProcessChildren(value: TJSONObject);
var
aValue: TJSONData;
index: integer;
begin
aValue := Value.Find('file');
if assigned(aValue) then
begin
ProcessFile(aValue.AsString);
end;
aValue := Value.Find('children');
if Assigned(aValue) then
begin
begin
if (aValue.JSONType = jtArray) then
ProcessChildrens(aValue as TJSONArray)
else if (Value.JSONType = jtObject) then
ProcessChildren(aValue as TJSONObject);
end;
end;
end;
procedure TStructureProcessor.ProcessChildrens(JSonSection: TJSONArray);
var
idx: integer;
obj: TJSONObject;
begin
for idx := 0 to JSonSection.Count - 1 do
begin
ProcessChildren(JSonSection.Objects[idx]);
end;
end;
procedure TStructureProcessor.visitObject(Value: TJSONObject);
var
aValue: TJSONData;
index: integer;
begin
aValue := Value.Find('file');
if assigned(aValue) then
begin
ProcessFile(aValue.AsString);
end;
aValue := Value.Find('children');
if Assigned(aValue) then
begin
begin
if (aValue.JSONType = jtArray) then
ProcessChildrens(aValue as TJSONArray)
else if (Value.JSONType = jtObject) then
ProcessChildren(aValue as TJSONObject);
end;
end;
end;
procedure TStructureProcessor.process;
begin
ParseFile;
visit(FJSonRoot);
SaveFile;
end;
Credo che, anche se ancora non funziona a dovere il mio programma, queste classi possono essere un esempio su come processare file json.
;)
Stilgar