5

我正在使用 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 or "b" : x.

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

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

我做了什么 ?:

  • 我尝试通过将值放在双引号下并使用 escape() 函数编码值来将 JSONata 脚本转换为 JSON。
  • 拥有 JSON 后,我会查找子表达式中提到的路径(如 data.Email)

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

  • 这种方法的问题是:

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

1 回答 1

2

我认为您最好的选择可能是将您的表达式转换为 JSONata AST,然后将它们合并到一个新的 AST 中。

这是一个超级简单的例子:

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
                }
              ]
            }
          ]
        ]
      }
    ]
  ]
}
于 2019-10-09T19:06:37.283 回答