如何使用带空格的 JSON 键名将 JSON 转换为 Ballerina 中的记录或映射类型

How to Convert JSON to record or map type in Ballerina with JSON key names with spaces

我从 [1] 得到一个 JSON,由于 json 中键的命名,我无法直接使用 hadling JSON 芭蕾舞女演员:
方法 1:直接使用 json 值:

string s = check j.x.y.z;

方法 2:使用任何数据的特定于应用程序的用户定义子类型:
无法使用 cloneWithType 或直接分配给用户定义的记录类型

我的解决方法是:

type AllStockData record {
    string open;
    string high;
    string low;
    string close;
    string volume;
};
AllStockData[] stockData = [];

public function main() returns @tainted  error? {

http:Client httpClient = check new ("https://www.alphavantage.co");
json jsonPayload = check httpClient->get("/query?function=TIME_SERIES_INTRADAY&symbol="+searchSymbol.toUpperAscii()+"&interval=5min&apikey="+apiKey, targetType = json);

map<json> allData = <map<json>>jsonPayload;
foreach json item in <map<json>>allData["Time Series (5min)"] {
    map<json> stockItem = <map<json>>item;
    AllStockData stock = { 
        open: stockItem["1. open"].toString(), 
        high: stockItem["2. high"].toString(), 
        low:  stockItem["3. low"].toString(),
        close: stockItem["4. close"].toString(), 
        volume: stockItem["5. volume"].toString()
    };
    stockData.push(stock);
}

我想知道是否有更好的方法来做到这一点?

在 Ballerina 中处理 JSON 时,我更喜欢使用特定于应用程序的类型。您可以在 Ballerina 中使用带引号的标识符将完整的 json 有效负载映射到应用程序指定的类型。我使用查询表达式将堆栈数据条目过滤到数组中。还有其他略有不同的方法可以实现相同的目的。

请注意,我使用 Ballerina Swan Lake Alpha 3 测试了此代码。

import ballerina/io;
import ballerina/http;

type StockQuery record {|
    MetaData 'Meta\ Data;
    TimeSeries5min 'Time\ Series\ \(5min\);
|};

type MetaData record {|
    string '1\.\ Information;
    string '2\.\ Symbol;
    string '3\.\ Last\ Refreshed;
    string '4\.\ Interval;
    string '5\.\ Output\ Size;
    string '6\.\ Time\ Zone;
|};

type TimeSeries5min record {|
    StockData...;
|};

type StockData record {|
    string '1\.\ open;
    string '2\.\ high;
    string '3\.\ low;
    string '4\.\ close;
    string '5\.\ volume;
|};

public function main() returns error? {
    http:Client httpClient = check new ("https://www.alphavantage.co");
    json jsonPayload = check httpClient->get("/query?function=TIME_SERIES_INTRADAY&symbol=IBM&interval=5min&apikey=demo", 
targetType = json);

    StockQuery stockQuery = check jsonPayload.cloneWithType(StockQuery);
    TimeSeries5min timeSeries = stockQuery.Time\ Series\ \(5min\);
    StockData[] stockDataArr = from var key in timeSeries.keys()
                               let StockData? stockData = timeSeries[key]
                               where stockData is StockData
                               select stockData;

    io:println(stockDataArr);
}