Hey Y'all,
It's rather intriguing that the Wiki example contains the unit
fpjson and then parses the JSON with the most insecure method ever: A pointer to the string.
Well, continuing my collection of
TestSomething applications, I've done one that uses both the return of a JSON Array and the return of a JSON Object from the Google Translate service.
I'm attaching a screenshot of the app after it translates.
I'm also attaching the project itself.
If you want to see if I make any changes then feel free to have a look at the GitHub repo:
https://github.com/gcarreno/TestGoogleTranslateThis is the, slightly changed, HTTP get function:
function TfrmMain.CallGoogleTranslate(AURL: String): TJSONStringType;
var
client: TFPHTTPClient;
doc: TStringList;
begin
Result:= EmptyStr;
doc:=TStringList.Create;
client:=TFPHTTPClient.Create(nil);
try
client.Get(AURL,doc);
Result:=doc.Text;
finally
doc.Free;
client.Free;
end;
end;
This is the call to the service and parsing the JSON Array return:
procedure TfrmMain.actArraysTranslateExecute(Sender: TObject);
var
URL: String;
Index: integer;
strResponse: TJSONStringType;
jdResponse, jdTranslation, jdTranslationArray: TJSONData;
jaTranslation, jaTranslationArray: TJSONArray;
begin
actArraysTranslate.Enabled:= False;
memArraysTo.Clear;
panArrayDetectedLanguage.Caption:= EmptyStr;
Application.ProcessMessages;
try
if Length(memArraysFrom.Text) = 0 then
begin
ShowMessage('Need something to translate');
exit;
end;
if (cobArrayFrom.ItemIndex <= 0) and (cobArrayTo.ItemIndex <= 0) then
begin
ShowMessage('Cannot have language detection on both sides');
exit;
end;
URL:='https://translate.googleapis.com/translate_a/single?client=gtx'
+'&q='+HTTPEncode(memArraysFrom.Text)
+'&sl='+cArrayShortLanguages[cobArrayFrom.ItemIndex]
+'&tl='+cArrayShortLanguages[cobArrayTo.ItemIndex]
+'&dt=t'
+'&ie=UTF-8&oe=UTF-8'
;
//ShowMessage(URL);
strResponse:= CallGoogleTranslate(URL);
try
jdResponse:= GetJSON(strResponse);
//memArraysTo.Append(jdResponse.FormatJSON); exit;
jdTranslation:= jdResponse.FindPath('[0]');
if (jdTranslation <> nil) and (jdTranslation.JSONType = jtArray) then
begin
jaTranslation:= TJSONArray(jdTranslation);
for index:= 0 to Pred(jaTranslation.Count) do
begin
jdTranslationArray:= jaTranslation[Index];
if (jdTranslationArray <> nil) and (jdTranslationArray.JSONType = jtArray) then
begin
jaTranslationArray:= TJSONArray(jdTranslationArray);
memArraysTo.Append(Trim(jaTranslationArray[0].AsString));
end;
end;
if cobArrayFrom.ItemIndex = 0 then
begin
panArrayDetectedLanguage.Caption:= Format(cSourceLanguage, [
ShortCodetoLongCode(jdResponse.FindPath('[2]').AsString)
]);
end;
end;
finally
jdResponse.Free;
end;
finally
Application.ProcessMessages;
actArraysTranslate.Enabled:= True;
end;
end;
This is the same call code but parsing the JSON object result:
procedure TfrmMain.actObjectTranslateExecute(Sender: TObject);
var
URL: String;
Index: integer;
strResponse: TJSONStringType;
jdResponse: TJSONData;
joTranslation, joSentence: TJSONObject;
jaSentencesArray: TJSONArray;
begin
actObjectTranslate.Enabled:= False;
memObjectTo.Clear;
panObjectDetectedLanguage.Caption:= EmptyStr;
Application.ProcessMessages;
try
if Length(memObjectFrom.Text) = 0 then
begin
ShowMessage('Need something to translate');
exit;
end;
if (cobObjectFrom.ItemIndex <= 0) and (cobObjectTo.ItemIndex <= 0) then
begin
ShowMessage('Cannot have language detection on both sides');
exit;
end;
URL:='https://translate.googleapis.com/translate_a/single?client=gtx'
+'&q='+HTTPEncode(memObjectFrom.Text)
+'&sl='+cArrayShortLanguages[cobObjectFrom.ItemIndex]
+'&tl='+cArrayShortLanguages[cobObjectTo.ItemIndex]
+'&dt=t&dj=1'
+'&ie=UTF-8&oe=UTF-8'
;
//ShowMessage(URL);
strResponse:= CallGoogleTranslate(URL);
try
jdResponse:= GetJSON(strResponse);
//memObjectTo.Append(jdResponse.FormatJSON); exit;
if (jdResponse <> nil) and (jdResponse.JSONType = jtObject) then
begin
joTranslation:= TJSONObject(jdResponse);
jaSentencesArray:= TJSONArray(joTranslation.FindPath(cJSONSentences));
for Index:=0 to Pred(jaSentencesArray.Count) do
begin
joSentence:= TJSONObject(jaSentencesArray[Index]);
memObjectTo.Append(Trim(joSentence.Get(cJSONTranslation,'')));
end;
if cobObjectFrom.ItemIndex = 0 then
begin
panObjectDetectedLanguage.Caption:= Format(cSourceLanguage, [
ShortCodetoLongCode(joTranslation.Get(cJSONSource,''))
]);
end;
end;
finally
jdResponse.Free;
end;
finally
Application.ProcessMessages;
actObjectTranslate.Enabled:= True;
end;
end;
I had fun doing it and I hope this can prove useful to someone.
Cheers,
Gus