简体   繁体   English

合并两个 JSONata 表达式

[英]Merging two JSONata expressions

I am using JSONata for performing JSON to JSON transformation.我正在使用 JSONata 执行 JSON 到 JSON 的转换。

For some unique reasons, I want to merge two JSONata expressions:由于一些独特的原因,我想合并两个 JSONata 表达式:

As an example:举个例子:

Parent Expression:父表达式:

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 & "!"
       }       
  }
`;

Also I have few simple assignment kind of JSONata expression like:我也有一些简单的 JSONata 表达式,例如:

Expression 1:表达式 1:

{
   "source" : source
}

Expression 2:表达式 2:

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

I would like to add above two expressions to expressions defined using script .我想将以上两个表达式添加到使用script定义的表达式中。

So after adding these two expressions, I should be able to get:所以添加这两个表达式后,我应该能够得到:

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
       }       
  }
`;

How do I do using javascript/JSONata?如何使用 javascript/JSONata?

Background and constraints:背景和限制:

  1. Child Expressions (expression 1 and 2 in the example) (that is supposed to be added into Parent expression) will always be simple assignment like "a": xyz or "b": x .子表达式(示例中的表达式 1 和 2)(应该添加到父表达式中)将始终是简单的赋值,例如"a": xyz or "b": x

  2. Child Expressions may already be present in parent expression.子表达式可能已经存在于父表达式中。 In that case, it replaces assignment.在这种情况下,它取代了赋值。

  3. Also I want to delete some json paths from parent expression (ofcouse, if it is present) like If delete path data.Email .我还想从父表达式(当然,如果存在)中删除一些 json 路径,例如 If delete path data.Email

What I have done?我做了什么? :

  • I tried to convert JSONata script to JSON by putting values under double quotes and encoding value using escape() function.我尝试通过将值放在双引号下并使用 escape() function 对值进行编码,将 JSONata 脚本转换为 JSON。
  • Once I have JSON, I look for path mentioned in child expression (like data.Email)一旦我有了 JSON,我就会寻找子表达式中提到的路径(如 data.Email)

    • If path exists: replace its value如果路径存在:替换它的值
    • If path does not exist: create path and assign value如果路径不存在:创建路径并赋值
    • If path is supposed to be deleted: simply delete it.如果路径应该被删除:只需删除它。
  • Once I have done processing above JSON, I convert it to JSONata script by removing quotes using bunch of regex and then applying unescape() method for decoding.一旦我完成了 JSON 以上的处理,我通过使用一堆正则表达式删除引号,然后应用 unescape() 方法进行解码,将其转换为 JSONata 脚本。

  • The problem with this approach is:这种方法的问题是:

    • It is not reliable (regex matching and replacement is not fullproof)它不可靠(正则表达式匹配和替换不是完全证明)
    • I am not sure whether every JSONata (which does not declare any functions) can be converted to valid JSON always.我不确定是否可以将每个 JSONata(未声明任何函数)始终转换为有效的 JSON。

I think that your best bet might be to translate your expressions to the JSONata AST and then merge them into a new AST.我认为您最好的选择可能是将您的表达式转换为 JSONata AST ,然后将它们合并到一个新的 AST 中。

Here's a super simple example:这是一个超级简单的例子:

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() 

The problem is what to do with your new AST.问题是如何处理你的新 AST。 In my case I also wrote a custom serializer to turn the AST back into a JSONata string, and evaluate that.在我的例子中,我还编写了一个自定义序列化程序来将 AST 转换回 JSONata 字符串,并对其进行评估。


ASTs in use使用中的 AST

AST for Expression 1表达式 1 的 AST

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

AST for Expression 2表达式 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
                }
              ]
            }
          ]
        ]
      }
    ]
  ]
}

Combined AST组合 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
                }
              ]
            }
          ]
        ]
      }
    ]
  ]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM