Here is a sample code from Embarcadero help ( http://docwiki.embarcadero.com/RADStudio/XE5/en/JSON ):
you can convert the string representation of JSON to JSON with one of the following code snippets.
Using ParseJSONValue :
procedure ConsumeJsonString; var LJSONObject: TJSONObject; begin LJSONObject := nil; try { convert String to JSON } LJSONObject := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(GJSONString), 0) as TJSONObject; { output the JSON to console as String } Writeln(LJSONObject.ToString); finally LJSONObject.Free; end;
This approach fails with an invalid class type different from line to line !!
Use Analysis :
procedure ConsumeJsonBytes; var LJSONObject: TJSONObject; begin LJSONObject := nil; try LJSONObject := TJsonObject.Create; { convert String to JSON } LJSONObject.Parse(BytesOf(GJSONString), 0); { output the JSON to console as String } Writeln(LJSONObject.ToString); finally LJSONObject.Free; end; end;
In the Embarcadero example, the JSON input is declared as a string as a string:
const GJSONString = '{' + ' "name": {'+ ' "A JSON Object": {' + ' "id": "1"' + ' },' + ' "Another JSON Object": {' + ' "id": "2"' + ' }' + ' },' + ' "totalobjects": "2"' + '}';
JSON is processed from BetFair. It is valid (verified from http://jsonformatter.curiousconcept.com/ and http://www.freeformatter.com/json-validator.html and http://jsonlint.com/ ):
[{ "caption": "Get the number of soccer markets", "methodName": "SportsAPING/v1.0/listEventTypes", "params": { "filter": { "eventTypeIds": [ 1 ] } } }, { "caption": "Get the next horse race in the UK", "methodName": "SportsAPING/v1.0/listMarketCatalogue", "params": { "filter": { "eventTypeIds": [ 7 ], "marketCountries": [ "GB" ], "marketTypeCodes": [ "WIN" ], "marketStartTime": { "from": "2013-04-11T11:03:36Z" } }, "sort": "FIRST_TO_START", "maxResults": "1", "marketProjection": [ "COMPETITION", "EVENT", "EVENT_TYPE", "MARKET_DESCRIPTION", "RUNNER_DESCRIPTION" ] } }, { "caption": "Get the 2 best prices, rolled up to £10 for the London Mayor Election 2016", "methodName": "SportsAPING/v1.0/listMarketBook", "params": { "marketIds": [ "1.107728324" ], "priceProjection": { "priceData": [ "EX_BEST_OFFERS" ], "exBestOffersOverrides": { "bestPricesDepth": "2", "rollupModel": "STAKE", "rollupLimit": "10" } } } }, { "caption": "Get my current unmatched bets", "methodName": "SportsAPING/v1.0/listCurrentOrders", "params": { "orderProjection": "EXECUTABLE" } }, { "caption": "Get my application keys", "methodName": "AccountAPING/v1.0/getDeveloperAppKeys", "params": { } }]
I do not declare this as a string, but I read it from a file:
TFile.ReadAllText(aFileName);
Reading file successfully.
Here is the code that causes the problem. I used approach 2 as recommended in the Embarcadero docs as shown above. This failed. I split the approach into more variables for debugging purposes.
According to the documents Embarcadero vParseResult will be a negative value if parsing for any reason is not possible. Is not. However, vJSONPair ends with zero, even if the parsing succeeded (second line after the attempt), which throws an exception:
procedure TfMain.loadScenarioData(aFilename: string); var vJSONString: string; vJSONScenario: TJSONObject; vJSONPair: TJSONPair; vJSONScenarioEntry: TJSONValue; vJSONScenarioValue: string; I: Int16; vParseResult: Integer; begin vJSONString := TFile.ReadAllText(aFileName); vJSONScenario := nil; try vJSONScenario := TJSONObject.Create; vParseResult := vJSONScenario.Parse(BytesOf(vJSONString),0); if vParseResult >= 0 then begin //BetFair Specific 'caption' key vJSONPair := vJSONScenario.Get('caption'); vJSONScenarioEntry := vJSONPair.JsonValue; vJSONScenarioValue := vJSONScenarioEntry.Value; cbScenario.Items.Add(vJSONScenarioValue); end; finally vJSONScenario.Free; end; end;
Things like this, where there is no adequate documentation for the IDE and language, or where the documentation is not complete or adequate, is a terrible waste of time and gives me problems with shutting down. I need to solve problems using the language and libraries, and not solve problems with them or more in terms of inadequate, ambiguous, and hard-to-reach documentation.