将 JSON table 转换为 JSON 树

Convert JSON table to JSON tree

我有 SQL 查询的结果 JSON 格式

value = [
    {"Machine": "Mach 1", "Device": "Dev a", "Identifier": "HMI 1"},
    {"Machine": "Mach 1", "Device": "Dev a", "Identifier": "HMI 2"},
    {"Machine": "Mach 1", "Device": "Dev b", "Identifier": "HMI 3"},
    {"Machine": "Mach 1", "Device": "Dev c", "Identifier": "HMI 5"},
    {"Machine": "Mach 2", "Device": "Dev c", "Identifier": "HMI 6"},
    {"Machine": "Mach 2", "Device": "Dev d", "Identifier": "HMI 7"},
    {"Machine": "Mach 3", "Device": "Dev e", "Identifier": "HMI 8"}
]

我正在尝试生成以下形式的树:

Tree to be generated
[ ]- Mach 1
 +[ ]- Dev a
 |  +-- HMI 2
 |  +-- HMI 3
 +[ ]- Dev c
    +-- HMI 5
[ ]- Mach 2
 +[ ]- Dev c
 |  +-- HMI 6
 +[ ]- Dev d
 |  +-- HMI 7
 +[ ]- Dev e
    +-- HMI 8

函数的输出将由 Inductive Automation's Perspective Tree component 使用,其格式为:

items = [
  {
    "label": "Mach 1",
    "expanded": true,
    "data": "",
    "items": [
      {
        "label": "Dev a",
        "expanded": true,
        "data": "",
        "items": [
          {
            "label": "HMI 1",
            "expanded": true,
            "data": {
              "Identifier": "HMI1",
              "Device": "Dev a",
              "Machine": "Mach 1"
            },
            "items": []
          },
          {
            "label": "HMI 2",
            "expanded": true,
            "data": {
              "Identifier": "HMI2",
              "Device": "Dev a",
              "Machine": "Mach 1"
            },
            "items": []
          }

        ]
      },
      {
        "label": "Dev b",
        "expanded": true,
        "data": "",
        "items": [
          {
            "label": "HMI 3",
            "expanded": true,
            "data": {
              "Identifier": "HMI3",
              "Device": "Dev b",
              "Machine": "Mach 1"
            },
            "items": []
          }
        ]
      }

    ]
  },

…

我已经为树深度三创建了一些线性 Python 代码,但我想修改它以自动处理 [=43 返回的树深度从 1 到 6(左右)的代码=]查询。 (上面的示例输入和输出是三级的。)不幸的是,我无法弄清楚如何修改它以使用可变列数的递归。

图 1. 我的惰性代码的结果(应要求提供)。

谁能推荐一种使用 Python 的方法 - 我正在使用的 Ignition 应用程序的脚本语言?

非常感谢。

您需要提供键在层次结构中向下钻取的顺序。这是一个很好的做法,因为字典中键的顺序可能不代表所需的顺序。

将这些键作为列表后,您可以使用它迭代地深入挖掘层次结构。

def makeForest(values, levels):
    items = []  # The top level result array
    paths = {}  # Objects keyed by path
    root = { "items": items }  # Dummy: super root of the forest
    for data in values:
        parent = root
        path = ""
        for key in levels:
            label = data[key]
            path += repr([label])
            node = paths.get(path, None)
            if not node:
                node = {
                    "label": data[key],
                    "expanded": True,
                    "data": "",
                    "items": []
                }
                paths[path] = node
                parent["items"].append(node)
            parent = node
        parent["data"] = data
    return items

# Example use:
value = [{"Machine": "Mach 1", "Device": "Dev a", "Identifier": "HMI 1"},{"Machine": "Mach 1", "Device": "Dev a", "Identifier": "HMI 2"},{"Machine": "Mach 1", "Device": "Dev b", "Identifier": "HMI 3"},{"Machine": "Mach 1", "Device": "Dev c", "Identifier": "HMI 5"},{"Machine": "Mach 2", "Device": "Dev c", "Identifier": "HMI 6"},{"Machine": "Mach 2", "Device": "Dev d", "Identifier": "HMI 7"},{"Machine": "Mach 3", "Device": "Dev e", "Identifier": "HMI 8"}]
forest = makeForest(value, ["Machine", "Device", "Identifier"])
print(forest)