JSONATA:跟踪递归路径的变平递归
我有一个任意深度的嵌套,递归的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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信“父”路径运算符是您想要的: 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