JSONATA:跟踪递归路径的变平递归

发布于 2025-01-24 03:52:51 字数 9227 浏览 0 评论 0原文

我有一个任意深度的嵌套,递归的json,一个节点可以是更多节点的父(即它具有结构包含节点的数组,这就是schema 或fieldGroup节点),也可以是叶子(field节点)。 我尝试使用jsonata将其映射到扁平的结构中。我很难跟踪递归路径 - 在这种情况下,我需要在每个递归映射的字段内构建ID的路径,但我不能。

具有三个嵌套级别的源JSON(“ House No。”是级别3):

{
  "schema": {
    "id": "S05000058",
    "label": "Request to breed mice",
    "structure": [
      {
        "contains": {
          "field": {
            "id": "F05001343",
            "label": "Accept terms and conditions"
          }
        }
      },
      {
        "contains": {
          "field": {
            "id": "F05001344",
            "label": "Agree to share registration with ministry of mice"
          }
        }
      },
      {
        "contains": {
          "fieldGroup": {
            "id": "G05000496",
            "label": "Requesting person",
            "structure": [
              {
                "contains": {
                  "field": {
                    "id": "F05000059",
                    "label": "Last name"
                  }
                }
              },
              {
                "contains": {
                  "field": {
                    "id": "F05000060",
                    "label": "First name"
                  }
                }
              },
              {
                "contains": {
                  "fieldGroup": {
                    "id": "G05000428",
                    "label": "Street address",
                    "structure": [
                      {
                        "contains": {
                          "field": {
                            "id": "F00000053",
                            "label": "Street"
                          }
                        }
                      },
                      {
                        "contains": {
                          "fieldGroup": {
                            "id": "G05000429",
                            "label": "House no",
                            "structure": [
                              {
                                "contains": {
                                  "field": {
                                    "id": "F00000016",
                                    "label": "Number"
                                  }
                                }
                              },
                              {
                                "contains": {
                                  "field": {
                                    "id": "F00000016",
                                    "label": "Appendix"
                                  }
                                }
                              }
                            ]
                          }
                        }
                      }
                    ]
                  }
                }
              },
              {
                "contains": {
                  "fieldGroup": {
                    "id": "G00000113",
                    "label": "Location",
                    "structure": [
                      {
                        "contains": {
                          "field": {
                            "id": "F00000054",
                            "label": "Postal code"
                          }
                        }
                      },
                      {
                        "contains": {
                          "field": {
                            "id": "F00000035",
                            "label": "City"
                          }
                        }
                      }
                    ]
                  }
                }
              },
              {
                "contains": {
                  "field": {
                    "id": "F05000523",
                    "label": "Country"
                  }
                }
              }
            ]
          }
        }
      }
    ]
  }
}

我的JSONATA映射使用后代路径操作员**从第二个嵌套级别开始递归浮式野外群。

”要在**递归中访问父节点的ID递归(最后$ mapfields()在下面的调用):

(
    $mapFields := function($datenfelder, $prefix) {
        $datenfelder.{
            "fields": [
                {
                    "label": label,
                    "idPath": $prefix & '.' & id
                }
            ]                                
        }
    };
    { 
    "idPath": schema.id,
    "sections": $append(
        /* top-level fields go into general section */
        {
            "title": "Top level fields",
            "fieldGroups": [
                {
                    "title": "",
                    "rows": $mapFields(schema.structure.contains.field, schema.id)
                }
            ]
        },
        /* subsequent sections contain top-level field groups */
        schema.structure.contains.fieldGroup.{
            "title": label,
            "idPath": $$.schema.id & '.' & id,
            "fieldGroups": [
                $append(
                    {
                        "title": "",
                        "rows": $mapFields(structure.contains.field, $$.schema.id & '.' & id)
                    },            
                    /* create fieldGroups recursively */
                    structure.contains.**.fieldGroup.{
                        "title": label,

                        /* how to build group idPath from third level: */
                        "idPath": $$.schema.id & '.' & id,
                        
                        /* how to pass recursive path prefix here: */
                        "rows": $mapFields($.structure.contains.field, ???) 
                    }
                )
            ]                 
        }
    )
})

我的jsonata无法从“街道”“街道地址”(在第二级上)产生完整的IDPath:

{
  "idPath": "S05000058",
  "sections": [
    {
      "title": "Top level fields",
      "fieldGroups": [
        {
          "title": "",
          "rows": [
            {
              "fields": [
                {
                  "label": "Accept terms and conditions",
                  "idPath": "S05000058.F05001343"
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "Agree to share registration with ministry of mice",
                  "idPath": "S05000058.F05001344"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "title": "Requesting person",
      "idPath": "S05000058.G05000496",
      "fieldGroups": [
        {
          "title": "",
          "rows": [
            {
              "fields": [
                {
                  "label": "Last name",
                  "idPath": "S05000058.G05000496.F05000059"
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "First name",
                  "idPath": "S05000058.G05000496.F05000060"
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "Country",
                  "idPath": "S05000058.G05000496.F05000523"
                }
              ]
            }
          ]
        },
        {
          "title": "Street address",
          "idPath": "S05000058.G05000428",
          "rows": {
            "fields": [
              {
                "label": "Street",
                "idPath": ".F00000053" /* incomplete */
              }
            ]
          }
        },
        {
          "title": "House no",
          
          /* incomplete, should be "S05000058.G05000428.G05000429": */
          "idPath": "S05000058.G05000429", 
          "rows": [
            {
              "fields": [
                {
                  "label": "Number",
                  "idPath": ".F00000016" /* incomplete */
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "Appendix",
                  "idPath": ".F00000016" /* incomplete */
                }
              ]
            }
          ]
        },
        {
          "title": "Location",
          "idPath": "S05000058.G00000113",
          "rows": [
            {
              "fields": [
                {
                  "label": "Postal code",
                  "idPath": ".F00000054" /* incomplete */
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "City",
                  "idPath": ".F00000035" /* incomplete */
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

请注意,请注意它不足通过$$。架构。ID& '。' & ID到递归$ mapfields()呼叫,如第三级的“ House no”现场组所示 - 从第三级开始的所有字段都将获得一个固定的前缀反映实际递归深度。

我还尝试过像如何使用JSONATA?将嵌套的对象变为单个深度对象,但是我没有设法迭代struction> struction recursion期间。

I have a nested, recursive JSON of arbitrary depth where a node can either be a parent of more nodes (i.e. it has a structure array containing nodes, which is the case for schema or fieldGroup nodes) or it can be a leaf (field node).
I try to use JSONata to map it to a flattened structure. I have difficulty to track the recursion path - in this case I need to build a path of ids inside each recursively mapped field, but I can't.

Source JSON with three levels of nesting ("House no." is level 3):

{
  "schema": {
    "id": "S05000058",
    "label": "Request to breed mice",
    "structure": [
      {
        "contains": {
          "field": {
            "id": "F05001343",
            "label": "Accept terms and conditions"
          }
        }
      },
      {
        "contains": {
          "field": {
            "id": "F05001344",
            "label": "Agree to share registration with ministry of mice"
          }
        }
      },
      {
        "contains": {
          "fieldGroup": {
            "id": "G05000496",
            "label": "Requesting person",
            "structure": [
              {
                "contains": {
                  "field": {
                    "id": "F05000059",
                    "label": "Last name"
                  }
                }
              },
              {
                "contains": {
                  "field": {
                    "id": "F05000060",
                    "label": "First name"
                  }
                }
              },
              {
                "contains": {
                  "fieldGroup": {
                    "id": "G05000428",
                    "label": "Street address",
                    "structure": [
                      {
                        "contains": {
                          "field": {
                            "id": "F00000053",
                            "label": "Street"
                          }
                        }
                      },
                      {
                        "contains": {
                          "fieldGroup": {
                            "id": "G05000429",
                            "label": "House no",
                            "structure": [
                              {
                                "contains": {
                                  "field": {
                                    "id": "F00000016",
                                    "label": "Number"
                                  }
                                }
                              },
                              {
                                "contains": {
                                  "field": {
                                    "id": "F00000016",
                                    "label": "Appendix"
                                  }
                                }
                              }
                            ]
                          }
                        }
                      }
                    ]
                  }
                }
              },
              {
                "contains": {
                  "fieldGroup": {
                    "id": "G00000113",
                    "label": "Location",
                    "structure": [
                      {
                        "contains": {
                          "field": {
                            "id": "F00000054",
                            "label": "Postal code"
                          }
                        }
                      },
                      {
                        "contains": {
                          "field": {
                            "id": "F00000035",
                            "label": "City"
                          }
                        }
                      }
                    ]
                  }
                }
              },
              {
                "contains": {
                  "field": {
                    "id": "F05000523",
                    "label": "Country"
                  }
                }
              }
            ]
          }
        }
      }
    ]
  }
}

My JSONata mapping uses the descendants path operator ** to flatten fieldGroups recursively, starting from the second nesting level.

https://try.jsonata.org/lfQdZcAe-

My problem is that I do not know how to get access to the ids of the parent nodes during ** recursion, therefore my $mapFields() function is unable to build an idPath for the recursion (last $mapFields() invocation below):

(
    $mapFields := function($datenfelder, $prefix) {
        $datenfelder.{
            "fields": [
                {
                    "label": label,
                    "idPath": $prefix & '.' & id
                }
            ]                                
        }
    };
    { 
    "idPath": schema.id,
    "sections": $append(
        /* top-level fields go into general section */
        {
            "title": "Top level fields",
            "fieldGroups": [
                {
                    "title": "",
                    "rows": $mapFields(schema.structure.contains.field, schema.id)
                }
            ]
        },
        /* subsequent sections contain top-level field groups */
        schema.structure.contains.fieldGroup.{
            "title": label,
            "idPath": $.schema.id & '.' & id,
            "fieldGroups": [
                $append(
                    {
                        "title": "",
                        "rows": $mapFields(structure.contains.field, $.schema.id & '.' & id)
                    },            
                    /* create fieldGroups recursively */
                    structure.contains.**.fieldGroup.{
                        "title": label,

                        /* how to build group idPath from third level: */
                        "idPath": $.schema.id & '.' & id,
                        
                        /* how to pass recursive path prefix here: */
                        "rows": $mapFields($.structure.contains.field, ???) 
                    }
                )
            ]                 
        }
    )
})

My JSONata fails to produce complete idPaths starting from the fieldGroup "Street address" (which is on the second level):

{
  "idPath": "S05000058",
  "sections": [
    {
      "title": "Top level fields",
      "fieldGroups": [
        {
          "title": "",
          "rows": [
            {
              "fields": [
                {
                  "label": "Accept terms and conditions",
                  "idPath": "S05000058.F05001343"
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "Agree to share registration with ministry of mice",
                  "idPath": "S05000058.F05001344"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "title": "Requesting person",
      "idPath": "S05000058.G05000496",
      "fieldGroups": [
        {
          "title": "",
          "rows": [
            {
              "fields": [
                {
                  "label": "Last name",
                  "idPath": "S05000058.G05000496.F05000059"
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "First name",
                  "idPath": "S05000058.G05000496.F05000060"
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "Country",
                  "idPath": "S05000058.G05000496.F05000523"
                }
              ]
            }
          ]
        },
        {
          "title": "Street address",
          "idPath": "S05000058.G05000428",
          "rows": {
            "fields": [
              {
                "label": "Street",
                "idPath": ".F00000053" /* incomplete */
              }
            ]
          }
        },
        {
          "title": "House no",
          
          /* incomplete, should be "S05000058.G05000428.G05000429": */
          "idPath": "S05000058.G05000429", 
          "rows": [
            {
              "fields": [
                {
                  "label": "Number",
                  "idPath": ".F00000016" /* incomplete */
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "Appendix",
                  "idPath": ".F00000016" /* incomplete */
                }
              ]
            }
          ]
        },
        {
          "title": "Location",
          "idPath": "S05000058.G00000113",
          "rows": [
            {
              "fields": [
                {
                  "label": "Postal code",
                  "idPath": ".F00000054" /* incomplete */
                }
              ]
            },
            {
              "fields": [
                {
                  "label": "City",
                  "idPath": ".F00000035" /* incomplete */
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Note that it is not sufficient to pass $$.schema.id & '.' & id to the recursive $mapFields() call, as shown by the "House No" fieldGroup on the third level - all fields starting from the third level would get a fixed prefix which does not reflect the actual depth of recursion.

I have also tried to create a recursion manually as in How to flatten nested object to single depth object with JSONata?, but I didn't manage to iterate over the structure array during recursion.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁拥 2025-01-31 03:52:51

我相信“父”路径运算符是您想要的: https://stedi.link/nr2ax3z

可以检查母公司在文档中的工作方式: https://docs.jsonata.org/路径操作员#-Parent

I believe the "parent" path operator is what you want here: https://stedi.link/NR2Ax3Z

You can check how the parent operator works in the docs: https://docs.jsonata.org/path-operators#-parent

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文