python - 创建流程树形式的 json 文件。在蟒蛇
问题描述
在一个简单的问题上,我需要一些帮助。
我正在尝试从此转换 json 文件的内容:
{ "Timestamp": "Timestamp",
"name": "SVCHOST.EXE",
"icon": "binary_icon.png",
"Process": SVCHOST.EXE,
"Pid": "876",
"PPID": "500"],
"children": [Process details])
},
{ "Timestamp":"Timestamp",
"name": "LSAS.EXE",
"icon": "binary_icon.png",
"Process": "LSAS.EXE",
"Pid": "500",
"PPID": "4"],
"children": [Process details])
},
{ "Timestamp":"Timestamp",
"name": "SYSTEM",
"icon": "binary_icon.png",
"Process": "SYSTEM",
"Pid": "4",
"PPID": "0"],
"children": [Process details])
}
对此:
{
"name": "Root",
"children": [
{
"name": "4",
"children": [
{
"name": "500",
"children": [
{
"name": "876",
"children": []
}
]
}
]
}
}
最后创建一个节点树图。
但是经过大量的试验和错误,仍然没有接近我需要的输出。我要求一些指针,提示或技巧。任何帮助深表感谢。
谢谢,
这是我最近的尝试。
import json
links = ({
"Timestamp": "Timestamp",
"name": "SVCHOST.EXE",
"icon": "binary_icon.png",
"Process": "SVCHOST.EXE",
"Pid": "876",
"PPID": "500",
"children": "Process_details"
},
{
"Timestamp":"Timestamp",
"name": "LSAS.EXE",
"icon": "binary_icon.png",
"Process": "LSAS.EXE",
"Pid": "500",
"PPID": "4",
"children": "Process_details"
},
{
"Timestamp":"Timestamp",
"name": "SYSTEM",
"icon": "binary_icon.png",
"Process": "SYSTEM",
"Pid": "4",
"PPID": "0",
"children": "Process_details"
})
parent_proc_node = {}
root = {'name': 'Root', 'children': []}
for item in procs:
parent_node = parent_proc_node.get(item['Pid'])
if not parent_node:
parent_proc_node[item['Pid']] = parent_node = {'name': item['PPID']}
root['children'].append(parent_node)
parent_proc_node[item['PPID']] = child_node = {'name': item['Pid']}
parent_node.setdefault('children', []).append(child_node)
print json.dumps(root, indent=4)
电流输出:
{
"name": "Root",
"children": [
{
"name": "500",
"children": [
{
"name": "876",
"children": [
{
"name": "500",
"children": [
{
"name": "4"
}
]
}
]
}
]
}
}
输出现在是我想要的,但我仍然无法正确地将父进程与子进程匹配。我究竟做错了什么?
正确的输出应该是这样的:
{
"name": "Root",
"children": [
{
"name": "4",
"children": [
{
"name": "500",
"children": [
{
"name": "876",
"children": [
{
"name": ""
}
]
}
]
}
]
}
}
解决方案
这是一些我认为你想要的代码。它处理links
(我把它变成了一个列表,因为 JSON 没有元组),将它转换为嵌套结构,您显示为最终正确的输出。我还添加了一些新记录,以便一些父母有多个孩子。
诀窍是首先创建一个字典 ( ids
) 来捕获进程 ID 的父子关系。
import json
links = [
{
"Timestamp": "Timestamp",
"name": "SVCHOST.EXE",
"icon": "binary_icon.png",
"Process": "SVCHOST.EXE",
"Pid": "876",
"PPID": "500",
"children": "Process_details"
},
{
"Timestamp": "Timestamp",
"name": "LSAS.EXE",
"icon": "binary_icon.png",
"Process": "LSAS.EXE",
"Pid": "500",
"PPID": "4",
"children": "Process_details"
},
{
"Timestamp": "Timestamp",
"name": "LSAS.EXE",
"icon": "binary_icon.png",
"Process": "LSAS.EXE",
"Pid": "510",
"PPID": "4",
"children": "Process_details"
},
{
"Timestamp": "Timestamp",
"name": "LSAS.EXE",
"icon": "binary_icon.png",
"Process": "LSAS.EXE",
"Pid": "600",
"PPID": "510",
"children": "Process_details"
},
{
"Timestamp": "Timestamp",
"name": "SYSTEM",
"icon": "binary_icon.png",
"Process": "SYSTEM",
"Pid": "4",
"PPID": "0",
"children": "Process_details"
}
]
# Create a dict linking each pid to its parent
ids = {}
for d in links:
# Use "0" as the ppid if "PPID" field is an empty string
ppid, pid = d["PPID"] or "0", d["Pid"]
ids.setdefault(ppid, []).append(pid)
print(ids)
# Nest the data for each pid in its parent's dict
def insert(lst, ppid, name):
if ppid in ids:
children = []
lst.append({"name": name, "children": children})
for pid in ids[ppid]:
insert(children, pid, pid)
else:
children = [{"name": ""}]
lst.append({"name": name, "children": children})
nested = []
insert(nested, "0", "Root")
print(json.dumps(nested[0], indent=4))
输出
{'500': ['876'], '4': ['500', '510'], '510': ['600'], '0': ['4']}
{
"name": "Root",
"children": [
{
"name": "4",
"children": [
{
"name": "500",
"children": [
{
"name": "876",
"children": [
{
"name": ""
}
]
}
]
},
{
"name": "510",
"children": [
{
"name": "600",
"children": [
{
"name": ""
}
]
}
]
}
]
}
]
}