如何使用jq将嵌套站点地图JSON转为带括号标记的页面路径列表?
使用jq将嵌套站点地图转换为路径列表
需求说明
将给定的嵌套JSON站点地图,转换为包含所有页面路径的列表,其中blocks中的标题需用括号包裹。
原始站点地图JSON
{ "sitemap": { "tree": { "node": [ { "text": "Main", "blocks": { "block": [ { "title": "Header" }, { "title": "General" }, { "title": "Message" }, { "title": "Daily" }, { "title": "Recognition" }, { "title": "Policies" } ] }, "children": { "node": [ { "text": "Hub", "blocks": null, "children": { "node": [ { "text": "Handbook", "blocks": null, "children": null }, { "text": "Jobs", "blocks": null, "children": null }, { "text": "Perks", "blocks": null, "children": null }, { "text": "Benefits", "blocks": null, "children": null } ] } }, { "text": "Resources", "blocks": null, "children": { "node": [ { "text": "Forms", "blocks": null, "children": null }, { "text": "Procedures", "blocks": null, "children": null }, { "text": "Training", "blocks": null, "children": null }, { "text": "Scripts", "blocks": null, "children": null }, { "text": "Marketing", "blocks": null, "children": { "node": [ { "text": "Logos", "blocks": null, "children": null }, { "text": "Brochures", "blocks": null, "children": null }, { "text": "Signage", "blocks": null, "children": null } ] } }, { "text": "Tips & Tricks", "blocks": null, "children": null } ] } }, { "text": "About", "blocks": null, "children": { "node": [ { "text": "Strategy", "blocks": null, "children": null } ] } } ] } }, { "text": "Search", "blocks": null, "children": null }, { "text": "Logins", "blocks": null, "children": { "node": [ { "text": "One", "blocks": null, "children": null }, { "text": "Two", "blocks": null, "children": null } ] } } ] } } }
jq转换命令
def walk_nodes($prefix): # 输出当前节点的路径 [$prefix + [.text]] # 处理当前节点下的blocks,生成带括号的路径 + (if .blocks and .blocks.block then .blocks.block | map($prefix + [.text, "(\\(.title))"]) else [] end) # 递归处理子节点,拼接前缀路径 + (if .children and .children.node then .children.node | map(walk_nodes($prefix + [.text])) | flatten(1) else [] end); # 从根节点开始遍历所有node .sitemap.tree.node | map(walk_nodes([])) | flatten(1)
命令解释
walk_nodes($prefix):自定义递归函数,接收当前路径前缀$prefix,处理单个节点:- 生成当前节点的完整路径(前缀+当前节点text)
- 若节点包含
blocks,遍历每个block生成带括号标题的路径 - 若节点有子节点,递归调用函数并更新路径前缀,最后扁平化递归结果
- 根节点处理:从
sitemap.tree.node起始,对每个节点调用递归函数,最终扁平化所有结果得到目标列表
转换结果
[ [ "Main" ], [ "Main", "(Header)" ], [ "Main", "(General)" ], [ "Main", "(Message)" ], [ "Main", "(Daily)" ], [ "Main", "(Recognition)" ], [ "Main", "(Policies)" ], [ "Main", "Hub" ], [ "Main", "Hub", "Handbook" ], [ "Main", "Hub", "Jobs" ], [ "Main", "Hub", "Perks" ], [ "Main", "Hub", "Benefits" ], [ "Main", "Resources" ], [ "Main", "Resources", "Forms" ], [ "Main", "Resources", "Procedures" ], [ "Main", "Resources", "Training" ], [ "Main", "Resources", "Scripts" ], [ "Main", "Resources", "Marketing" ], [ "Main", "Resources", "Marketing", "Logos" ], [ "Main", "Resources", "Marketing", "Brochures" ], [ "Main", "Resources", "Marketing", "Signage" ], [ "Main", "Resources", "Tips & Tricks" ], [ "Main", "About" ], [ "Main", "About", "Strategy" ], [ "Search" ], [ "Logins" ], [ "Logins", "One" ], [ "Logins", "Two" ] ]
内容的提问来源于stack exchange,提问作者parleer
相关产品推荐
相关产品推荐

