首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用TJSONDataObject正确语法读取嵌套对象中JSON字符串的值

使用TJSONDataObject正确语法读取嵌套对象中JSON字符串的值
EN

Stack Overflow用户
提问于 2020-12-17 08:31:57
回答 2查看 253关注 0票数 1

有谁能帮助我正确的语法来访问嵌套对象中的字符串,使用Andreas的JSONDataObjects

我有一个从API返回的JSON字符串,该API包含一个客户数组,后面跟着一个游标分页对象(meta)。

代码语言:javascript
复制
  {
  "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
               }
}

最后我试图在before对象中获取metaafter的值。

我已经尝试过的

代码语言:javascript
复制
var  Obj: TJsonObject;
       AfterID : string;
  
  begin
  Obj := TJsonObject.Parse(theJSON) as TJsonObject;
  AfterID :=    Obj['meta']['cursors']['after']  ; 

问题我得到的错误消息不能将对象转换为字符串

我也试过

代码语言:javascript
复制
  var  
     Obj: TJsonObject;
     AfterID : string;
   begin   
   obj :=  Obj['meta'];
   Obj := Obj['cursors'];
   AfterID := Obj['after'];

问题我得到的错误消息不能将对象转换为字符串

我也尝试过许多其他的语法组合,但我不会把所有这些问题都弄乱!

我感到困惑,因为我的语法是正确的,当使用与另一个API稍微不同的JSON做同样的事情时,该API具有更简单的游标分页结构

代码语言:javascript
复制
{
  "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,使用

代码语言:javascript
复制
var
      Obj : TJsonObject;
      nextID : string;
begin
 Obj := TJsonObject.Parse(TheReturnedJSON) as TJDOJsonObject; 
 nextID := Obj['paging']['next'];

我得到返回的正确值。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-17 08:54:24

TJsonObject的默认[]属性是它的Values[]属性,它返回一个TJsonDataValueHelper

代码语言:javascript
复制
property Values[const Name: string]: TJsonDataValueHelper read GetValue write SetValue; default;

因此,reading Obj['cursors']返回一个TJsonDataValueHelper,而不是一个TJsonObject

TJsonDataValueHelper的默认[]属性是它的O[]属性,它返回表示JSON对象的TJsonDataValueHelper,而不是JSON字符串:

代码语言:javascript
复制
property O[const Name: string]: TJsonDataValueHelper read {$IFDEF BCB}GetObj{$ELSE}GetObject{$ENDIF} write SetObject; default;

TJsonDataValueHelper有一个S[]属性来读取字符串值:

代码语言:javascript
复制
property S[const Name: string]: string read GetObjectString write SetObjectString;        // returns '' if property doesn't exist, auto type-cast except for array/object

所以,试试这个吧:

代码语言:javascript
复制
AfterID := Obj['meta']['cursors'].S['after']; 
代码语言:javascript
复制
nextID := Obj['paging'].S['next']; 

或者,根本不要使用TJsonDataValueHelperTJsonObject有一个返回TJsonObjectO[]属性和一个用于读取字符串的S[]属性:

代码语言:javascript
复制
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

例如:

代码语言:javascript
复制
AfterID := Obj.O['meta'].O['cursors'].S['after']; 
代码语言:javascript
复制
nextID := Obj.O['paging'].S['next']; 
票数 1
EN

Stack Overflow用户

发布于 2020-12-17 10:41:35

顺便提一句,我将补充一下雷米的回答,因为我的示例JSON中的'before'值是null,所以我发现我不得不使用下面的代码来避免在将该值读取为Obj.Values['meta'].O['cursors'].S['before'];时出现另一个类型传递错误

代码语言:javascript
复制
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只是猜测而已。我很想知道这些文件都在哪里!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65337123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档