You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何区分JsonObject中数值数组与对象数组类型属性?

问题

如何区分“MonthQuota”和“Forecast”属性?在实际程序中,我使用JsonObject类和动态ProDataSet进行递归解析,请给出适配该场景的解决方案。

我需要解析的JSON中,“MonthQuota”是数值数组,“Forecast”是对象数组,示例JSON如下:

{  
        "ttSalesRep": [  
            {  
                "SalesRep": "BBB",  
                "RepName": "Brawn, Bubba B.",  
                "Region": "East",  
                "MonthQuota": [  
                    1600,1648,1697,1748,1800,1854  
                ],  
                "Forecast": [  
                    {
                        "Month1": "Enero",  
                        "Amount1": 111.1  
                    },  
                    {  
                      "Month1": "Marzo",  
                      "Amount1": 111.2  
                    }  
                ]  
            }  
        ]  
    }  

注:原示例中“Forcast”“Amont1”为拼写错误,已修正为“Forecast”“Amount1”

由于需要以不同方式解析这两个属性,我尝试使用GetType方法,但“MonthQuota”和“Forecast”的GetType返回值均为5,无法区分。以下是复现问题的示例代码:

DEFINE VARIABLE myParser     AS ObjectModelParser NO-UNDO.  
DEFINE VARIABLE myConstruct  AS JsonConstruct     NO-UNDO.  
DEFINE VARIABLE myJsonObj    AS JsonObject        NO-UNDO.  
DEFINE VARIABLE myArray      AS CHAR EXTENT       NO-UNDO.  
DEFINE VARIABLE my_JSON_File AS CHARACTER         NO-UNDO.  


my_JSON_File = "myJsonFile.json".  

myParser    = NEW ObjectModelParser().  
myConstruct = myParser:ParseFile(my_JSON_File).  
myJsonObj   = CAST(myConstruct, JsonObject).  

myArray = myJsonObj:GetJsonArray("ttSalesRep"):GetJsonObject(1):GetNames().  
MESSAGE  
    myArray[4] "=" myJsonObj:GetJsonArray("ttSalesRep"):GetJsonObject(1):GetType(myArray[4]) SKIP  
    myArray[5] "=" myJsonObj:GetJsonArray("ttSalesRep"):GetJsonObject(1):GetType(myArray[5]) SKIP  
VIEW-AS ALERT-BOX.  

解决方案

方法1:通过数组元素的类型区分

GetType()返回5表示两者都是JsonArray类型,无法直接区分,但可以读取数组首个元素的类型判断:

  • 数值数组的元素类型为3(JsonNumber)
  • 对象数组的元素类型为4(JsonObject)

示例代码:

DEFINE VARIABLE salesRepObj AS JsonObject NO-UNDO.
DEFINE VARIABLE quotaArray AS JsonArray NO-UNDO.
DEFINE VARIABLE forecastArray AS JsonArray NO-UNDO.

salesRepObj = myJsonObj:GetJsonArray("ttSalesRep"):GetJsonObject(1).

// 处理MonthQuota数值数组
quotaArray = salesRepObj:GetJsonArray("MonthQuota").
IF quotaArray:GetType(1) = 3 THEN DO:
    DEFINE VARIABLE i AS INTEGER NO-UNDO.
    DEFINE VARIABLE quotaVal AS DECIMAL NO-UNDO.
    DO i = 1 TO quotaArray:Count():
        quotaVal = quotaArray:GetJsonNumber(i):DecimalValue.
        // 将quotaVal写入动态ProDataSet对应字段
    END.
END.

// 处理Forecast对象数组
forecastArray = salesRepObj:GetJsonArray("Forecast").
IF forecastArray:GetType(1) = 4 THEN DO:
    DEFINE VARIABLE i AS INTEGER NO-UNDO.
    DEFINE VARIABLE forecastObj AS JsonObject NO-UNDO.
    DO i = 1 TO forecastArray:Count():
        forecastObj = forecastArray:GetJsonObject(i).
        DEFINE VARIABLE monthName AS CHARACTER NO-UNDO.
        DEFINE VARIABLE amount AS DECIMAL NO-UNDO.
        monthName = forecastObj:GetJsonString("Month1"):Value.
        amount = forecastObj:GetJsonNumber("Amount1"):DecimalValue.
        // 将monthName和amount写入动态ProDataSet子表
    END.
END.

方法2:结合属性名称预判(适用于固定结构场景)

如果JSON结构固定,可直接通过属性名称指定解析逻辑:

  • 遇到MonthQuota按数值数组解析
  • 遇到Forecast按对象数组解析

递归解析时的示例逻辑:

PROCEDURE ProcessJsonObject:
    DEFINE INPUT PARAMETER pJsonObj AS JsonObject NO-UNDO.
    DEFINE INPUT PARAMETER pDataSet AS HANDLE NO-UNDO.
    DEFINE INPUT PARAMETER pBuffer AS HANDLE NO-UNDO.

    DEFINE VARIABLE names AS CHARACTER EXTENT NO-UNDO.
    DEFINE VARIABLE i AS INTEGER NO-UNDO.
    DEFINE VARIABLE propName AS CHARACTER NO-UNDO.

    names = pJsonObj:GetNames().
    DO i = 1 TO EXTENT(names):
        propName = names[i].
        CASE propName:
            WHEN "MonthQuota":
                // 数值数组解析逻辑
                DEFINE VARIABLE arr AS JsonArray NO-UNDO.
                arr = pJsonObj:GetJsonArray(propName).
                // 写入动态ProDataSet对应字段
            WHEN "Forecast":
                // 对象数组解析逻辑
                DEFINE VARIABLE arr AS JsonArray NO-UNDO.
                arr = pJsonObj:GetJsonArray(propName).
                // 创建动态ProDataSet子表行并写入属性值
            OTHERWISE:
                // 普通属性解析
                CASE pJsonObj:GetType(propName):
                    WHEN 2: // JsonString
                        pBuffer:BUFFER-FIELD(propName):VALUE = pJsonObj:GetJsonString(propName):Value.
                    WHEN 3: // JsonNumber
                        pBuffer:BUFFER-FIELD(propName):VALUE = pJsonObj:GetJsonNumber(propName):DecimalValue.
                    // 其他类型处理
                END CASE.
        END CASE.
    END.
END PROCEDURE.

方法3:通过类型转换异常判断(适配空数组场景)

如果数组可能为空,可尝试将元素转换为JsonObject,失败则判定为数值数组:

DEFINE VARIABLE arr AS JsonArray NO-UNDO.
DEFINE VARIABLE isObjectArray AS LOGICAL NO-UNDO.

arr = salesRepObj:GetJsonArray(propName).
isObjectArray = FALSE.

IF arr:Count() > 0 THEN DO:
    DO ON ERROR UNDO, LEAVE:
        CAST(arr:GetJsonConstruct(1), JsonObject).
        isObjectArray = TRUE.
    END.
END.

IF isObjectArray THEN DO:
    // 对象数组处理逻辑
END ELSE DO:
    // 数值数组处理逻辑
END.

内容的提问来源于stack exchange,提问作者SSosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:53:13