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

如何在Ballerina中转换记录类型并剔除空值可选字段?

问题

我对接的部分API仅接收已填充的节点,若请求负载中包含空值节点会返回错误。示例如下:

场景1:源数据含空值节点

{
    "name": {
        "firstName": "John",
        "middleName": "Quincy",
        "lastName": "Smith",
        "title": ""
    }
}

接收API支持title字段,但要求不传入空值的title节点,转换后的预期负载为:

{
    "givenName": "John",
    "middleName": "Quincy",
    "surname": "Smith"
}

场景2:源数据title字段有值

{
    "name": {
        "firstName": "John",
        "middleName": "Quincy",
        "lastName": "Smith",
        "title": "Mr"
    }
}

转换后的负载需包含该字段:

{
    "givenName": "John",
    "middleName": "Quincy",
    "surname": "Smith",
    "title": "Mr"
}

请问如何在Ballerina中实现该需求?


解决方案

在Ballerina中可以通过条件判断+动态结构构建实现该需求,核心是只将非空字段加入最终请求负载。以下是具体实现:

完整代码示例

import ballerina/json;
import ballerina/io;

// 定义源数据结构
type SourceName record {
    string firstName;
    string middleName;
    string lastName;
    string title?; // 标记为可选字段,对应可能为空的情况
};

type SourcePayload record {
    SourceName name;
};

// 定义目标数据结构
type TargetPayload record {
    string givenName;
    string middleName;
    string surname;
    string title?; // 可选字段,仅当源数据非空时添加
};

// 转换逻辑函数
function transformPayload(SourcePayload source) returns TargetPayload {
    // 初始化必填字段的目标结构
    TargetPayload target = {
        givenName: source.name.firstName,
        middleName: source.name.middleName,
        surname: source.name.lastName
    };

    // 仅当title为非空字符串时,添加到目标结构(trim处理空格空值)
    if source.name.title is string && source.name.title.trim() != "" {
        target.title = source.name.title;
    }

    return target;
}

// 测试两种场景
public function main() {
    // 测试空title场景
    SourcePayload sourceWithEmptyTitle = {
        name: {
            firstName: "John",
            middleName: "Quincy",
            lastName: "Smith",
            title: ""
        }
    };
    io:println("空title转换结果: ", json:toString(transformPayload(sourceWithEmptyTitle)));

    // 测试有值title场景
    SourcePayload sourceWithValidTitle = {
        name: {
            firstName: "John",
            middleName: "Quincy",
            lastName: "Smith",
            title: "Mr"
        }
    };
    io:println("有值title转换结果: ", json:toString(transformPayload(sourceWithValidTitle)));
}

代码说明

  1. 类型定义:用record明确源数据和目标数据的结构,将可能为空的title标记为可选字段(?),适配字段存在或缺失的场景。
  2. 转换逻辑:先构建必填字段的基础目标结构,再通过条件判断检查源数据的title是否为非空字符串(加入trim()处理纯空格的空值情况),满足条件则添加该字段到目标结构。
  3. 场景测试:在main函数中分别验证两种场景,输出转换后的JSON结果,确保符合预期。

扩展优化(多字段复用)

如果需要处理多个可能为空的字段,可以封装通用的非空字段添加函数,提升代码复用性:

// 通用函数:仅当值非空时添加到目标map
function addNonEmptyField(map<anydata> target, string key, string? value) {
    if value is string && value.trim() != "" {
        target[key] = value;
    }
}

调用方式:

function transformPayload(SourcePayload source) returns TargetPayload {
    map<anydata> targetMap = {
        "givenName": source.name.firstName,
        "middleName": source.name.middleName,
        "surname": source.name.lastName
    };

    addNonEmptyField(targetMap, "title", source.name.title);
    // 可添加更多字段处理,比如addNonEmptyField(targetMap, "suffix", source.name.suffix);

    return targetMap.cloneWithType();
}

这种方式更适合多字段的复杂转换场景,减少重复代码。

内容的提问来源于stack exchange,提问作者Dilan Sachintha Nayanajith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 23:40:30