设想
我在 Delphi 2009项目的各个地方使用了Andreas Hausladen的JsonDataObjects单元,现在我需要解析API调用远程服务器上的cpanel所返回的简单JSON。
大部分我都能做,但是在这种情况下返回的JSON看起来(至少在目前)有一个空对象{}
(不是null),我希望得到一些帮助(a)测试空对象,(b)如果对象不空,则从对象中获取一些值。
数据
cpanel API文档here指出,返回的JSON具有以下格式,其中元数据为空。
{
"apiversion": 3,
"func": "add_host",
"module": "Mysql",
"result": {
"data": null,
"errors": null,
"messages": null,
"metadata": { },
"status": 1,
"warnings": null
}
}
实际上文档是错的,我拿回来的数据是这样的形式,就是没有results
对象,但是metadata
对象还是空的,跟文档一样,不知道metadata
对象不空的时候会是什么样子,文档没有说。
{
"data":"MyData",
"errors":["The first error text"],
"warnings":null,
"status":0,
"messages":null,
"metadata":{}
}
那些问题
1.如何测试对象MainObj['metadata']
是否为空?它不是null
,因为它包含{}
,所以If MainObj['metadata'].isnull ...
返回false,代码进入else
部分。
1.一旦我测试了它是否为空,当它没有名称时,我如何提取对象的数据(假定为null)?
问题代码
这是一个小测试过程,演示了我解析这个数据时遇到的问题。大多数行都产生了预期的结果。问题出在对象MainObj['metadata']
上,它在JSON中(当前)是空的。
procedure TForm1.btn1Click(Sender: TObject);
const
THEJSON = ''
+' { '
+' "data":"MyData", '
+' "errors":["The first error text"], '
+' "warnings":null, '
+' "status":0, '
+' "messages":null, '
+' "metadata":{} '
+' } ';
var
MainObj, MetaDataObject: TJsonObject;
i : Integer;
begin
MainObj := TJsonObject.Parse(THEJSON) as TJsonObject;
try
if MainObj['data'].IsNull then
Memo2.Lines.Add('data = NULL')
else
Memo2.Lines.Add('data = ' + MainObj['data'].value);
if MainObj['warnings'].IsNull then
Memo2.Lines.Add('warnings = NULL')
else
Memo2.Lines.Add('warnings = ' + MainObj['warnings'].value);
if MainObj['status'].IsNull then
Memo2.Lines.Add('status = NULL')
else
Memo2.Lines.Add('status = ' + MainObj['status'].value);
if MainObj['messages'].IsNull then
Memo2.Lines.Add('messages = NULL')
else
Memo2.Lines.Add('messages = ' + MainObj['messages'].value);
if MainObj['errors'].IsNull then
Memo2.Lines.Add('errors = NULL')
else
for I := 0 to MainObj['errors'].count - 1 do
Memo2.Lines.Add('Error' + IntToStr(i) + ' = ' + MainObj['errors'].items[i]) ;
if MainObj['metadata'].isnull then
Memo2.Lines.Add('metadata = No object')
else
begin
//this is where it goes pear shaped!
MetaDataObject := TJsonObject.Parse(MainObj['metadata']) as TJsonObject; //cannot cast object to string???
try
Memo2.Lines.Add('metadata text is ' + MetaDataObject.ToString);
if MetaDataObject['????].isnull then / if MetaDataObject['????] is empty then //what goes here?
Memo2.Lines.Add('metadata = NULL')
else '
Memo2.Lines.Add('metadata = ' + MetaDataObject.Value);
finally
MetaDataObject.Free;
end;
end;
finally
MainObj.Free;
end;
end;
预期成果
data = MyData
warnings = NULL
status = 0
messages = NULL
Error0 = The first error text
接着是
metadata text is {}
metadata = NULL
或者,如果其中有数据,则后跟
metadata text is {"meta_1":"mymeta"}
metadata = mymeta
实际结果
data = MyData
warnings = NULL
status = 0
messages = NULL
Error0 = The first error text
后跟运行时错误“无法将对象强制转换为字符串”。
"我所尝试的"
if not Assigned(MetaDataObject) then ...
if not Assigned(MainObj['metadata']) then ...
if Assigned (TJsonObject(MainObj['metadata'])) then
MetaDataObject := TJsonObject.Parse(MainObj['metadata']) as TJsonObject;
我所看到的地方
1条答案
按热度按时间tcbh2hod1#
您已经知道如何从JSON对象访问子值。
当JSON对象为非空但没有子值(即为空)时,
TJsonObject.Count
属性将为0。因此,首先检查所需的值是否为null
,如果不是,则将该值作为TJsonObject
访问,并检查其Count
是否为0,然后相应地进行操作。例如: