使用Embarcadero代码示例使用TJSONObject解析有效JSON失败,出现异常
以下是Embarcadero帮助()中的示例代码: 您可以使用以下代码片段之一将JSON字符串表示转换为JSON 使用ParseJSONValue:使用Embarcadero代码示例使用TJSONObject解析有效JSON失败,出现异常,json,delphi,parsing,Json,Delphi,Parsing,以下是Embarcadero帮助()中的示例代码: 您可以使用以下代码片段之一将JSON字符串表示转换为JSON 使用ParseJSONValue: 过程ConsumeJsonString; 变量 LJSONObject:TJSONObject; 开始 LJSONObject:=nil; 尝试 {将字符串转换为JSON} LJSONObject:=TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(GJSONString),0)作为TJSONO
过程ConsumeJsonString;
变量
LJSONObject:TJSONObject;
开始
LJSONObject:=nil;
尝试
{将字符串转换为JSON}
LJSONObject:=TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(GJSONString),0)作为TJSONObject;
{将JSON作为字符串输出到控制台}
Writeln(LJSONObject.ToString);
最后
LJSONObject.Free;
结束;
这种方法失败了,因为as行上的类类型转换无效
使用解析:
过程消耗jsonbytes;
变量
LJSONObject:TJSONObject;
开始
LJSONObject:=nil;
尝试
LJSONObject:=TJsonObject.Create;
{将字符串转换为JSON}
解析(BytesOf(GJSONString),0);
{将JSON作为字符串输出到控制台}
Writeln(LJSONObject.ToString);
最后
LJSONObject.Free;
结束;
结束;
在Embarcadero示例中,输入JSON在代码中声明为字符串:
const
GJSONString=
'{' +
““名称”:{”+
““一个JSON对象”:{”+
““id”:“1”+
' },' +
““另一个JSON对象”:{”+
“id”:“2”+
' }' +
' },' +
““totalobjects”:“2”+
'}';
我正在处理的JSON来自BetFair。有效(通过和验证):
[{
“说明”:“获取足球市场的数量”,
“方法名称”:“SportsAPING/v1.0/listEventTypes”,
“参数”:{
“过滤器”:{
“EventTypeId”:[
1.
]
}
}
},
{
“说明”:“在英国参加下一场赛马”,
“方法名称”:“SportsAPING/v1.0/ListMarketCatalog”,
“参数”:{
“过滤器”:{
“EventTypeId”:[
7.
],
“市场国家”:[
“GB”
],
“市场类型代码”:[
“赢”
],
“市场启动时间”:{
“发件人”:“2013-04-11T11:03:36Z”
}
},
“排序”:“第一次开始”,
“maxResults”:“1”,
“市场预测”:[
“竞争”,
“活动”,
“事件类型”,
“市场描述”,
“跑步者描述”
]
}
},
{
“说明”:“为2016年伦敦市长选举获得2个最优惠价格,总计10英镑”,
“方法名称”:“SportsAPING/v1.0/listMarketBook”,
“参数”:{
“市场化”:[
"1.107728324"
],
“价格预测”:{
“价格数据”:[
“EX_BEST_优惠”
],
“exBestOffersOverrides”:{
“最佳价格深度”:“2”,
“汇总模型”:“桩”,
“rollupLimit”:“10”
}
}
}
},
{
“说明”:“获取我当前未匹配的赌注”,
“方法名称”:“SportsAPING/v1.0/listCurrentOrders”,
“参数”:{
“orderProjection”:“可执行文件”
}
},
{
“标题”:“获取我的应用程序密钥”,
“方法名”:“AccountAPING/v1.0/getDeveloperAppKeys”,
“参数”:{
}
}]
我不是将其声明为字符串,而是从文件中读取它,因此:
TFile.ReadAllText(aFileName);
文件读取成功
下面是导致问题的代码。我已经使用了Embarcadero文档中推荐的方法2,如上所述。那失败了。为了调试的目的,我将该方法拆分为多个变量
根据Embarcadero文件,vParseResult将为负值
如果解析因任何原因失败,则返回值。事实并非如此。但是,即使解析成功(try之后的第二行),vJSONPair最终还是为nil,这会导致异常:
过程TfMain.loadScenarioData(文件名:字符串);
变量
vJSONString:string;
vJSONScenario:TJSONObject;
vJSONPair:TJSONPair;
vJSONScenarioEntry:TJSONValue;
vJSONScenarioValue:字符串;
I:Int16;
vParseResult:整数;
开始
vJSONString:=TFile.ReadAllText(aFileName);
vJSONScenario:=零;
尝试
vJSONScenario:=TJSONObject.Create;
vParseResult:=vJSONScenario.Parse(BytesOf(vJSONString),0);
如果vParseResult>=0,则
开始
//BetFair特定的“标题”键
vJSONPair:=vJSONScenario.Get('caption');
vJSONScenarioEntry:=vJSONPair.JsonValue;
vJSONScenarioValue:=vJSONScenarioEntry.Value;
cbScenario.Items.Add(vJSONScenarioValue);
结束;
最后
免费;
结束;
结束;
这种没有足够的IDE和语言文档,或者文档不完整或不充分的情况是一种严重的时间浪费,给我带来了完成工作的问题。我需要使用语言和库来解决问题,而不是使用它们来解决问题,或者使用不充分、不明确和难以找到的文档来解决问题。
TJSONObject.ParseJSONValue()
如果解析失败,将返回一个nil
指针。Embarcadero的例子没有检查这种情况。如果解析失败,这将解释as
运算符引发的“无效类型转换”错误
TJSONObject.Parse()
如果解析失败,则返回-1。Embarcadero的例子没有检查这种情况
因为TJSONObject
解析字节,而不是字符,所以我建议您不要使用TFile.ReadAllText()
,它将读取字节并使用TEncoding.Default
将其解码为UTF-16(如果文件没有BOM)。在你的
procedure TfMain.loadScenarioData(aFilename: string);
var
vJSONBytes: TBytes;
vJSONScenario: TJSONValue;
vJSONArray: TJSONArray;
vJSONValue: TJSONValue;
vJSONObject: TJSONObject;
vJSONPair: TJSONPair;
vJSONScenarioEntry: TJSONValue;
vJSONScenarioValue: TJSONString;
begin
vJSONBytes := TFile.ReadAllBytes(aFileName);
vJSONScenario := TJSONObject.ParseJSONValue(vJSONBytes, 0);
if vJSONScenario <> nil then
try
//BetFair Specific 'caption' key
vJSONArray := vJSONScenario as TJSONArray;
for vJSONValue in vJSONArray do
begin
vJSONObject := vJSONValue as TJSONObject;
vJSONPair := vJSONObject.Get('caption');
vJSONScenarioEntry := vJSONPair.JsonValue;
vJSONScenarioValue := vJSONScenarioEntry as TJSONString;
cbScenario.Items.Add(vJSONScenarioValue.Value);
end;
finally
vJSONScenario.Free;
end;
end;
procedure TfMain.loadScenarioData(aFilename: string);
var
vJSONScenario: TJSONValue;
vJSONValue: TJSONValue;
begin
vJSONScenario := TJSONObject.ParseJSONValue(TFile.ReadAllBytes(aFileName), 0);
if vJSONScenario <> nil then
try
//BetFair Specific 'caption' key
for vJSONValue in vJSONScenario as TJSONArray do
begin
cbScenario.Items.Add(((vJSONValue as TJSONObject).Get('caption').JsonValue as TJSONString).Value);
end;
finally
vJSONScenario.Free;
end;
end;
procedure TfMain.loadScenarioData(aFilename: string);
var
vJSONBytes: TBytes;
vJSONScenario: TJSONObject;
vJSONArray: TJSONArray;
vJSONValue: TJSONValue;
vJSONObject: TJSONObject;
vJSONPair: TJSONPair;
vJSONScenarioEntry: TJSONString;
vJSONScenarioValue: string;
vParseResult: Integer;
begin
vJSONBytes := TFile.ReadAllBytes(aFileName);
vJSONScenario := TJSONObject.Create;
try
vParseResult := vJSONScenario.Parse(vJSONBytes, 0);
if vParseResult >= 0 then
begin
//BetFair Specific 'caption' key
vJSONArray := vJSONScenario.Get(0) as TJSONArray;
for vJSONValue in vJSONArray do
begin
vJSONObject := vJSONValue as TJSONObject;
vJSONPair := vJSONObject.Get('caption');
vJSONScenarioEntry := vJSONPair.JsonString;
vJSONScenarioValue := vJSONScenarioEntry.Value;
cbScenario.Items.Add(vJSONScenarioValue);
end;
end;
finally
vJSONScenario.Free;
end;
end;
procedure TfMain.loadScenarioData(aFilename: string);
var
vJSONScenario: TJSONObject;
vJSONValue: TJSONValue;
vParseResult: Integer;
begin
vJSONScenario := TJSONObject.Create;
try
vParseResult := vJSONScenario.Parse(TFile.ReadAllBytes(aFileName), 0);
if vParseResult >= 0 then
begin
//BetFair Specific 'caption' key
for vJSONValue in vJSONScenario.Get(0) as TJSONArray do
begin
cbScenario.Items.Add(((vJSONValue as TJSONObject).Get('caption').JsonValue as TJSONString).Value);
end;
end;
finally
vJSONScenario.Free;
end;
end;
procedure TfMain.loadScenarioData(aFilename: string);
var
vJSONScenario: ISuperObject;
vJSONArray: ISuperObject;
vJSONObject: ISuperObject;
vJSONScenarioValue: string;
I: Integer;
begin
vJSONScenario := TSuperObject.ParseFile(aFileName);
//BetFair Specific 'caption' key
vJSONArray := vJSONScenario.AsArray;
for I := 0 to vJSONArray.Length-1 do
begin
vJSONObject := vJSONArray[I].AsObject;
vJSONScenarioValue := vJSONObject.S['caption'];
cbScenario.Items.Add(vJSONScenarioValue);
end;
end;
var
vJSONBytes: TBytes;
vJSONScenario: TJSONValue;
vJSONArray: TJSONArray;
vJSONValue: TJSONValue;
vJSONObject: TJSONObject;
vJSONPair: TJSONPair;
vJSONScenarioEntry: TJSONString;
vJSONScenarioValue: TJSONValue;
begin
vJSONBytes := TFile.ReadAllBytes(aFileName);
vJSONScenario := TJSONObject.ParseJSONValue(vJSONBytes, 0);
if vJSONScenario <> nil then
try
//BetFair Specific 'caption' key
vJSONArray := vJSONScenario as TJSONArray;
for vJSONValue in vJSONArray do
begin
vJSONObject := vJSONValue as TJSONObject;
vJSONPair := vJSONObject.Get(pScenarioKey);
vJSONScenarioEntry := vJSONPair.JsonString;
//vJSONScenarioValue := vJSONScenarioEntry.Value;
vJSONScenarioValue := vJSONPair.JsonValue;
cbScenario.Items.Add(vJSONScenarioValue.ToString);
end;
finally
vJSONScenario.Free;
end;
end;