Мне нужна помощь по несколько простой проблеме.
Я пытаюсь преобразовать содержимое 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
), который фиксирует отношения родитель-потомок идентификаторов процессов.
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 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": ""
}
]
}
]
}
]
}
]
}
insert
опирается на структуру в ids
представляющую собой связанное дерево, и вам нужно вызвать insert
с корневым узлом этого дерева. Если у вас есть несколько деревьев, вам придется проделать еще немного работы, чтобы справиться с этим.
@PM 2Ring Извините, пожалуйста, обратите внимание на замечания PPID 0. Отсутствие обработки выполнения на моем конце. :) Ваш эскрипт отлично работает, для родителей с детьми. однако, если PID не имеет родителя, он не добавляется в корневой узел.
procs = [{
"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"
}
,
{
"Timestamp":"Timestamp",
"name": "ROUGEPROC",
"icon": "binary_icon.png",
"Process": "ROUGEPROC",
"Pid": "4322",
"PPID": "",
"children": "Process_details"
}]
# Create a dict linking each pid to its parent
ids = {}
for d in procs:
ppid, pid = d["PPID"], d["Pid"]
ids.setdefault(ppid, []).append(pid)
print(ids)
# Nest the data for each pid in its parent dict
def insert(lst, ppid, name):
if ppid in ids:
children = []
lst.append({"name": name, "children": children, "icon": "binary_icon.png"})
for pid in ids[ppid]:
insert(children, pid, pid)
else:
children = []
lst.append({"name": name, "children": children, "icon": "binary_icon.png"})
nested = []
insert(nested, "0", "PPID")
proc_report = {"name" :"HOSTNAME",
"icon": "win_os_icon.png",
"children": nested[0]["children"]
}
print(json.dumps(proc_report, indent=4))
Выход:
{'': ['4322'], '0': ['4'], '4': ['500'], '500': ['876']}
{
"children": [
{
"icon": "binary_icon.png",
"name": "4",
"children": [
{
"icon": "binary_icon.png",
"name": "500",
"children": [
{
"icon": "binary_icon.png",
"name": "876",
"children": []
}
]
}
]
}
],
"name": "HOSTNAME",
"icon": "win_os_icon.png"
}
for d in links:
поле «PPID» равно «», тогда преобразуйте его в «0», например, ppid, pid = d["PPID"] or "0", d["Pid"]
]
после «PPID» выглядят неправильно. Что случилось с соответствием[
?