gpt4 book ai didi

javascript - 合并两个 JSONata 表达式

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:23:24 25 4
gpt4 key购买 nike

我正在使用 JSONata 执行 JSON 到 JSON 的转换。

由于一些独特的原因,我想合并两个 JSONata 表达式:

举个例子:

父表达式:

var script = `
{
"data":
{
"name" : data.payload.Name.(FirstName & ' ' & LastName),
"alias": data.payload.Name.(Salutation & ' ' & FirstName),
"active": data.payload.Status = 'New' ? true : false,
"signature": "Have good day ," & data.payload.Name.FirstName & "!"
}
}
`;

我也有一些简单的赋值类型的 JSONata 表达式,比如:

表达式 1:

{
"source" : source
}

表达式 2:

{
"data": {
"email" : data.payload.Email
}
}

我想将以上两个表达式添加到使用 script 定义的表达式中。

所以在添加这两个表达式之后,我应该能够得到:

var script = `
{
"source": source,
"data":
{
"name" : data.payload.Name.(FirstName & ' ' & LastName),
"alias": data.payload.Name.(Salutation & ' ' & FirstName),
"active": data.payload.Status = 'New' ? true : false,
"signature": "Have good day ," & data.payload.Name.FirstName & "!",
"email": data.payload.Email
}
}
`;

如何使用 javascript/JSONata?

背景和限制:

  1. 子表达式(示例中的表达式 1 和 2)(应该添加到父表达式中)将始终是简单的赋值,如 "a": x.y.z 或 "b": x.

  2. 子表达式可能已经存在于父表达式中。在这种情况下,它会取代赋值。

  3. 我还想从父表达式中删除一些 json 路径(ofcouse,如果存在的话),例如 If delete path data.Email

我做了什么? :

  • 我尝试将 JSONata 脚本转换为 JSON,方法是将值放在双引号下并使用 escape() 函数对值进行编码。
  • 一旦我有了 JSON,我就会寻找子表达式中提到的路径(比如 data.Email)

    • 如果路径存在:替换它的值
    • 如果路径不存在:创建路径并赋值
    • 如果应该删除路径:只需删除它即可。
  • 完成 JSON 处理后,我通过使用一堆正则表达式删除引号并将其转换为 JSONata 脚本,然后应用 unescape() 方法进行解码。

  • 这种方法的问题是:

    • 不可靠(正则表达式匹配和替换不是完全可靠的)
    • 我不确定每个 JSONata(未声明任何函数)是否始终可以转换为有效的 JSON。

最佳答案

我认为您最好的选择可能是将您的表达式翻译成 JSONata AST然后将它们合并成一个新的 AST。

这是一个 super 简单的例子:

const ast1 = jsonata(expr1).ast();
const ast2 = jsonata(expr1).ast();

if (ast1.type !== "unary" || ast2.type!== "unary") throw Error("Only support unary expressions")

const combinedAst = {
"type": "unary",
"value": "{",
"lhs": [...ast1.lhs, ast2.lhs]
}

// TODO: Serialize the AST or inject it into jsonata()

问题是如何处理你的新 AST。在我的例子中,我还编写了一个自定义序列化程序来将 AST 转回 JSONata 字符串,并对其进行评估。


使用中的 AST

表达式 1 的 AST

{
"type": "unary",
"value": "{",
"position": 1,
"lhs": [
[
{
"value": "source",
"type": "string",
"position": 13
},
{
"type": "path",
"steps": [
{
"value": "source",
"type": "name",
"position": 22
}
]
}
]
]
}

表达式 2 的 AST

{
"type": "unary",
"value": "{",
"position": 1,
"lhs": [
[
{
"value": "data",
"type": "string",
"position": 10
},
{
"type": "unary",
"value": "{",
"position": 13,
"lhs": [
[
{
"value": "email",
"type": "string",
"position": 26
},
{
"type": "path",
"steps": [
{
"value": "data",
"type": "name",
"position": 33
},
{
"value": "payload",
"type": "name",
"position": 41
},
{
"value": "Email",
"type": "name",
"position": 47
}
]
}
]
]
}
]
]
}

组合 AST

{
"type": "unary",
"value": "{",
"position": 1,
"lhs": [
[
{
"value": "source",
"type": "string",
"position": 12
},
{
"type": "path",
"steps": [
{
"value": "source",
"type": "name",
"position": 20
}
]
}
],
[
{
"value": "data",
"type": "string",
"position": 30
},
{
"type": "unary",
"value": "{",
"position": 33,
"lhs": [
[
{
"value": "email",
"type": "string",
"position": 46
},
{
"type": "path",
"steps": [
{
"value": "data",
"type": "name",
"position": 53
},
{
"value": "payload",
"type": "name",
"position": 61
},
{
"value": "Email",
"type": "name",
"position": 67
}
]
}
]
]
}
]
]
}

关于javascript - 合并两个 JSONata 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58106179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com