使用 TJSONDataObject 读取嵌套对象中 JSON 字符串值的正确语法
Correct syntax to read the value of a JSON string inside nested object using TJSONDataObject
有人可以用正确的语法帮助我访问嵌套对象中的字符串,使用 JSON来自 Andreas Hausladen
的 DataObjects
我有一个从 API 返回的 JSON 字符串,其中包含一个客户数组,后跟一个游标分页对象(元),例如
{
"customers": [
{
"id": "CU000DWEQWMRN4",
"email": "theemail@outlook.com",
"metadata": {
"member_name": "BLOGGS jim",
"membership_id": "4088"
}
},
{
"id": "CU000DVEKR579S",
"email": "anotheremail@outlook.com",
"metadata": {
"membership_id": "5647"
}
}
],
"meta": {
"cursors": {
"before": null,
"after": "ID456"
},
"limit": 50
}
}
我试图在最后 meta
对象中获取 before
和 after
的值
我试过的
var Obj: TJsonObject;
AfterID : string;
begin
Obj := TJsonObject.Parse(theJSON) as TJsonObject;
AfterID := Obj['meta']['cursors']['after'] ;
问题
我收到错误消息 cannot convert object to string
我也试过了
var
Obj: TJsonObject;
AfterID : string;
begin
obj := Obj['meta'];
Obj := Obj['cursors'];
AfterID := Obj['after'];
问题
我收到错误消息 cannot convert object to string
我也尝试过许多其他语法组合,但我不会用所有这些来混淆问题!
我很困惑,因为我的语法是正确的,当我用一个稍微不同的 JSON 从另一个 API 返回时,我的语法是正确的,它具有更简单的游标分页结构,例如
{
"items": [
{
"event": "accepted",
"id": "G3wOhh",
"user-variables": {},
"log-level": "info",
"method": "smtp"
},
{
"event": "accepted",
"id": "KLT56",
"user-variables": {},
"log-level": "info",
"method": "smtp"
}
],
"paging": {
"previous": "line 4",
"first": "line 1",
"last": "line 12",
"next": "line 6"
}
}
用这个JSON,用
var
Obj : TJsonObject;
nextID : string;
begin
Obj := TJsonObject.Parse(TheReturnedJSON) as TJDOJsonObject;
nextID := Obj['paging']['next'];
我得到了正确的返回值
TJsonObject
的默认[]
属性是它的Values[]
属性,其中returns一个TJsonDataValueHelper
:
property Values[const Name: string]: TJsonDataValueHelper read GetValue write SetValue; default;
所以,阅读 Obj['cursors']
returns TJsonDataValueHelper
,而不是 TJsonObject
。
TJsonDataValueHelper
的默认[]
属性是它的O[]
属性,其中returns一个TJsonDataValueHelper
代表一个JSON 对象,不是 JSON 字符串:
property O[const Name: string]: TJsonDataValueHelper read {$IFDEF BCB}GetObj{$ELSE}GetObject{$ENDIF} write SetObject; default;
TJsonDataValueHelper
有一个 S[]
属性 来读取字符串值:
property S[const Name: string]: string read GetObjectString write SetObjectString; // returns '' if property doesn't exist, auto type-cast except for array/object
所以,试试这个:
AfterID := Obj['meta']['cursors'].S['after'];
nextID := Obj['paging'].S['next'];
或者,根本不使用 TJsonDataValueHelper
。 TJsonObject
有一个 O[]
属性,returns 一个 TJsonObject
,还有一个 S[]
属性 用于读取字符串:
property S[const Name: string]: string read GetString write SetString; // returns '' if property doesn't exist, auto type-cast except for array/object
...
property O[const Name: string]: TJsonObject read {$IFDEF BCB}GetObj{$ELSE}GetObject{$ENDIF} write SetObject; // auto creates object on first access
例如:
AfterID := Obj.O['meta'].O['cursors'].S['after'];
nextID := Obj.O['paging'].S['next'];
顺便说一句,我会在 Remy 的回答中补充说,由于我的示例 JSON 中 'before'
的值为 null
,我发现我必须使用以下代码避免在将该值读取为 Obj.Values['meta'].O['cursors'].S['before'];
时出现另一个类型转换错误
var
temp : variant;
BeforeID : string;
begin
//read the value into a variant by using .V just in case it's null.
//if it is then reading a string using .S gives an error
temp := Obj.Values['meta'].O['cursors'].V['before'];
if not VarIsNull(temp) then // it's not a null so we can convert to a string
BeforeID := VarToStr(temp)
else // it is null so assign whatever string is appropriate
BeforeID := '';
但使用 .V
只是一个猜测。我很想知道所有这些都记录在哪里!
有人可以用正确的语法帮助我访问嵌套对象中的字符串,使用 JSON来自 Andreas Hausladen
的 DataObjects我有一个从 API 返回的 JSON 字符串,其中包含一个客户数组,后跟一个游标分页对象(元),例如
{
"customers": [
{
"id": "CU000DWEQWMRN4",
"email": "theemail@outlook.com",
"metadata": {
"member_name": "BLOGGS jim",
"membership_id": "4088"
}
},
{
"id": "CU000DVEKR579S",
"email": "anotheremail@outlook.com",
"metadata": {
"membership_id": "5647"
}
}
],
"meta": {
"cursors": {
"before": null,
"after": "ID456"
},
"limit": 50
}
}
我试图在最后 meta
对象中获取 before
和 after
的值
我试过的
var Obj: TJsonObject;
AfterID : string;
begin
Obj := TJsonObject.Parse(theJSON) as TJsonObject;
AfterID := Obj['meta']['cursors']['after'] ;
问题 我收到错误消息 cannot convert object to string
我也试过了
var
Obj: TJsonObject;
AfterID : string;
begin
obj := Obj['meta'];
Obj := Obj['cursors'];
AfterID := Obj['after'];
问题 我收到错误消息 cannot convert object to string
我也尝试过许多其他语法组合,但我不会用所有这些来混淆问题!
我很困惑,因为我的语法是正确的,当我用一个稍微不同的 JSON 从另一个 API 返回时,我的语法是正确的,它具有更简单的游标分页结构,例如
{
"items": [
{
"event": "accepted",
"id": "G3wOhh",
"user-variables": {},
"log-level": "info",
"method": "smtp"
},
{
"event": "accepted",
"id": "KLT56",
"user-variables": {},
"log-level": "info",
"method": "smtp"
}
],
"paging": {
"previous": "line 4",
"first": "line 1",
"last": "line 12",
"next": "line 6"
}
}
用这个JSON,用
var
Obj : TJsonObject;
nextID : string;
begin
Obj := TJsonObject.Parse(TheReturnedJSON) as TJDOJsonObject;
nextID := Obj['paging']['next'];
我得到了正确的返回值
TJsonObject
的默认[]
属性是它的Values[]
属性,其中returns一个TJsonDataValueHelper
:
property Values[const Name: string]: TJsonDataValueHelper read GetValue write SetValue; default;
所以,阅读 Obj['cursors']
returns TJsonDataValueHelper
,而不是 TJsonObject
。
TJsonDataValueHelper
的默认[]
属性是它的O[]
属性,其中returns一个TJsonDataValueHelper
代表一个JSON 对象,不是 JSON 字符串:
property O[const Name: string]: TJsonDataValueHelper read {$IFDEF BCB}GetObj{$ELSE}GetObject{$ENDIF} write SetObject; default;
TJsonDataValueHelper
有一个 S[]
属性 来读取字符串值:
property S[const Name: string]: string read GetObjectString write SetObjectString; // returns '' if property doesn't exist, auto type-cast except for array/object
所以,试试这个:
AfterID := Obj['meta']['cursors'].S['after'];
nextID := Obj['paging'].S['next'];
或者,根本不使用 TJsonDataValueHelper
。 TJsonObject
有一个 O[]
属性,returns 一个 TJsonObject
,还有一个 S[]
属性 用于读取字符串:
property S[const Name: string]: string read GetString write SetString; // returns '' if property doesn't exist, auto type-cast except for array/object
...
property O[const Name: string]: TJsonObject read {$IFDEF BCB}GetObj{$ELSE}GetObject{$ENDIF} write SetObject; // auto creates object on first access
例如:
AfterID := Obj.O['meta'].O['cursors'].S['after'];
nextID := Obj.O['paging'].S['next'];
顺便说一句,我会在 Remy 的回答中补充说,由于我的示例 JSON 中 'before'
的值为 null
,我发现我必须使用以下代码避免在将该值读取为 Obj.Values['meta'].O['cursors'].S['before'];
var
temp : variant;
BeforeID : string;
begin
//read the value into a variant by using .V just in case it's null.
//if it is then reading a string using .S gives an error
temp := Obj.Values['meta'].O['cursors'].V['before'];
if not VarIsNull(temp) then // it's not a null so we can convert to a string
BeforeID := VarToStr(temp)
else // it is null so assign whatever string is appropriate
BeforeID := '';
但使用 .V
只是一个猜测。我很想知道所有这些都记录在哪里!