使用anytree将JSON转换为图像

时间:2019-06-24 17:16:43

标签: python json anytree

我正在尝试使用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")

Image generated by program

当我尝试按照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作为文本块而没有空格格式,在docs中需要逐行完成以捕获树结构。因此,似乎RenderTree(root)并没有按照第一个示例的Node样式格式化JSON。

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

1 个答案:

答案 0 :(得分:1)

让我们举一个概括的例子,即您几乎不需要手动处理。

进口

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

enter image description here


在Windows 10下使用GraphViz 2.38 测试