使用anytree将JSON转为图片

Using anytree to convert JSON to a image

我正在尝试使用 anytree 读取 JSON 文件并使用渲染树图将其导出为 png 图像。对于我创建它工作的节点的基本示例。

from anytree import RenderTree
from anytree import Node
from anytree.dotexport import RenderTreeGraph

root = Node("root")
s0 = Node("s0", parent=root)
s1 = Node("s1", parent=root)
t1 = Node("t1", parent=s0)

print(root)
RenderTreeGraph(root).to_picture("test.png")

当我尝试按照 docs

导入 json 文件时
from anytree.importer import JsonImporter
from anytree import RenderTree
from anytree import Node
from anytree.dotexport import RenderTreeGraph
importer = JsonImporter()
path = open("config.json")

root = importer.read(path)
tree = RenderTree(root)
print(tree)

RenderTreeGraph(tree).to_picture("test.png")

我收到以下错误:

Traceback (most recent call last): File "pyth.py", line 20, in <module> DotExporter(tree).to_dotfile("tree.dot") File "/home/user/.local/lib/python3.5/site-packages/anytree/exporter/dotexporter.py", line 214, in to_dotfile for line in self: File "/home/user/.local/lib/python3.5/site-packages/anytree/exporter/dotexporter.py", line 160, in __iter for node in self.__iter_nodes(indent, nodenamefunc, nodeattrfunc): File "/home/user/.local/lib/python3.5/site-packages/anytree/exporter/dotexporter.py", line 174, in __iter_nodes nodename = nodenamefunc(node) File "/home/user/.local/lib/python3.5/site-packages/anytree/exporter/dotexporter.py", line 142, in __default_nodenamefunc return node.name AttributeError: 'RenderTree' object has no attribute 'name'

print(tree) 通过管道传输到文本文件中,将 JSON 作为没有白色 space 格式的文本块提供,在文档中,这需要逐行完成捕获树结构。所以看起来 RenderTree(root) 没有在第一个示例的节点样式中格式化 JSON。

有人知道出了什么问题吗?是否还有其他步骤可以正确解析 JSON?

让我们举一个通用的例子,即你几乎不需要手动做任何事情。

进口

import anytree.exporter as atex
import anytree as at
import json

一个JSON

下面(i)a_str_json,我在https://json.org/example.html找到的一个玩具-json,代表内容你的文件名为 "config.json"(ii) a_dict,它的 python 转换版本。

a_str_json = ("""
{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}
""")

a_dict = json.loads(a_str_json)

核心工作

让我们定义 tree_builder,一个将通过递归探索 a_dict 来构建我们的树的函数。

def tree_builder(d, p_uid='root', l=0):

    for i, (k, v) in enumerate(d.items()):
        node_uid = 'l{}n{}'.format(l, i)
        node = nodes[k] = at.Node(
            name   = node_uid,
            key    = k,
            parent = nodes[p_uid]
        )
        if isinstance(v, dict):
            node.an_attr = ''
            tree_builder(v, k, l + 1)
        else:
            node.an_attr = v

...并使用它

root  = at.Node(name='root', key='root', an_attr='')
nodes = {'root' : root}
tree_builder(a_dict)

for pre, fill, node in at.RenderTree(root):
    print("%s%s|%s" % (pre, node.key, node.an_attr))

atex.DotExporter(
    root, nodeattrfunc = lambda n : 'label="{}\n{}"'.format(n.key, n.an_attr)
).to_picture("root.png")

产生

root|
└── glossary|
    ├── title|example glossary
    └── GlossDiv|
        ├── title|S
        └── GlossList|
            └── GlossEntry|
                ├── ID|SGML
                ├── SortAs|SGML
                ├── GlossTerm|Standard Generalized Markup Language
                ├── Acronym|SGML
                ├── Abbrev|ISO 8879:1986
                ├── GlossDef|
                │   ├── para|A meta-markup language, used to create markup languages such as DocBook.
                │   └── GlossSeeAlso|['GML', 'XML']
                └── GlossSee|markup


使用 GraphViz 2.38 在 windows10.

下测试